Java读取大JSON文件提取指定字段遇NumberFormatException问题求助
Hey fellow Java newbie, let's unpack what went wrong with your initial org.json.simple code, and why your Gson fix works perfectly!
Why the org.json.simple NumberFormatException Happened
The error java.lang.NumberFormatException: For input string: "18446744073709551615" boils down to a key limitation in how org.json.simple handles large numeric values:
- That string represents the maximum value for an unsigned 64-bit integer (2^64 - 1).
- Java's built-in
longtype is a signed 64-bit integer, with a maximum value of9223372036854775807—way smaller than the value in your JSON. - org.json.simple tries to parse all numeric values into Java's
Numbersubclasses (likeLong) automatically. When it hits this huge unsigned value, it can't fit it into a signedlong, causing an overflow and the exception. - Worst of all: even if this value has nothing to do with the
automatic -> kernel -> releasefield you care about, org.json.simple's strict parsing of every field breaks the entire process.
Your Working Gson Solution (With Minor Readability Tweaks)
Great call switching to Gson! Its parsing approach is far more flexible for cases like this: it doesn't force numeric values into Java's limited number types upfront. Instead, it keeps values as JsonElement instances until you explicitly convert them, letting you skip over problematic fields entirely.
Here's your code with a few small improvements to make it easier to follow:
import com.google.gson.JsonElement; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.google.gson.JsonReader; import com.google.gson.Gson; import java.io.FileReader; import java.io.IOException; public class JsonReleaseExtractor { public static void main(String[] args) { // Replace this with your actual desktop JSON file path String jsonFilePath = "C:\\Users\\YourName\\Desktop\\your-large-file.json"; // Use try-with-resources to auto-close the reader (cleaner than manual handling) try (JsonReader jsonReader = new JsonReader(new FileReader(jsonFilePath))) { Gson gson = new Gson(); JsonElement rootElement = gson.fromJson(jsonReader, JsonElement.class); // Navigate down to the "rows" array in your JSON structure JsonArray rowsArray = rootElement.getAsJsonObject().get("rows").getAsJsonArray(); // Loop through each row to extract the release value for (JsonElement rowElement : rowsArray) { JsonObject automaticObj = rowElement.getAsJsonObject().getAsJsonObject("automatic"); JsonObject kernelObj = automaticObj.getAsJsonObject("kernel"); String releaseValue = kernelObj.get("release").getAsString(); System.out.println(releaseValue); } } catch (IOException e) { System.err.println("Error reading the JSON file:"); e.printStackTrace(); } } }
Why This Gson Approach Works
Gson parses the entire JSON into a tree of JsonElement objects. When you access the release field and call getAsString(), you're explicitly telling Gson how to handle that value—bypassing any issues with large numeric fields elsewhere in the JSON. Gson won't attempt to parse those problematic values until you explicitly ask it to, so your target field extraction stays smooth.
内容的提问来源于stack exchange,提问作者Ch0p

