当使用 GSON 的 JsonReader 流式传输 Json 文件时,可以将对象转储为字符串吗?
When streaming a Json file with GSON's JsonReader, can you dump an object to string?
我在 Java 工作,使用 GSON 库处理巨大的 JSON 文档。
我绝对不能将它加载到内存中,它超过了 8G,如果我尝试加载它会导致 JVM 崩溃并出现 OOM。
所以我用JsonReader
来处理JSON的流。
有些时候我遇到 BEGIN_OBJECT
只想将对象的内容转储到字符串而不是处理每个单独的元素。
例如,我正在解析这样的东西:
[ { "SchemaVersion":"15.0.0.0","LibraryVersion":"16.0.7324.1200","ErrorInfo":{ "ErrorMessage":"Access denied. You do not have permission to perform this action or access this resource.","ErrorValue":null,"TraceCorrelationId":"03ab459e-7076-5000-c1a7-196f1fc54384","ErrorCode":-2147024891,"ErrorTypeName":"System.UnauthorizedAccessException" },"TraceCorrelationId":"03ab459e-7076-5000-c1a7-196f1fc54384" } ]
当我到达 ErrorInfo
时,我只想将其作为字符串而不是解析出来。我不想解析每一块。
代码如下:
try (InputStream is = (InputStream)response.getEntity();
InputStreamReader inputStreamReader = new InputStreamReader(is);
JsonReader jsonReader = new JsonReader(inputStreamReader)) {
if (jsonReader.peek() != JsonToken.BEGIN_ARRAY) {
return;
}
jsonReader.beginArray();
while (jsonReader.hasNext()) {
jsonReader.beginObject(); // Start of the default object on every request
jsonReader.skipValue(); // name SchemaVersion
jsonReader.skipValue(); // value
jsonReader.skipValue(); // name LibraryVersion
jsonReader.skipValue(); // value
jsonReader.skipValue(); // name ErrorInfo
if (jsonReader.peek() == JsonToken.BEGIN_OBJECT) {
// I want to dump the upcoming object to string here
...
是否可以转储给定开始对象的 json reader 的内容,直到它结束为字符串?
类似问题,但不完全相同:Get a dump of a section (object) of JSON
特别感谢https://whosebug.com/users/3389828/nikhil在评论中的回答。对于这种确切情况,您可以使用 Gson.fromJson(jsonReader, Map.class)
。
Gson gson = new Gson();
try (InputStream is = (InputStream)response.getEntity();
InputStreamReader inputStreamReader = new InputStreamReader(is);
JsonReader jsonReader = new JsonReader(inputStreamReader)) {
if (jsonReader.peek() != JsonToken.BEGIN_ARRAY) {
return;
}
jsonReader.beginArray();
while (jsonReader.hasNext()) {
Map header = gson.fromJson(jsonReader, Map.class);
if (header.get("ErrorInfo") != null) {
String errorDump = ((Map)header.get("ErrorInfo")).toString();
// Now I have the error dump I need but I also
// didn't load the entire thing into memory!
...
更多信息:https://javadeveloperzone.com/java-8/java-parse-large-json-file-gson-example/
我在 Java 工作,使用 GSON 库处理巨大的 JSON 文档。
我绝对不能将它加载到内存中,它超过了 8G,如果我尝试加载它会导致 JVM 崩溃并出现 OOM。
所以我用JsonReader
来处理JSON的流。
有些时候我遇到 BEGIN_OBJECT
只想将对象的内容转储到字符串而不是处理每个单独的元素。
例如,我正在解析这样的东西:
[ { "SchemaVersion":"15.0.0.0","LibraryVersion":"16.0.7324.1200","ErrorInfo":{ "ErrorMessage":"Access denied. You do not have permission to perform this action or access this resource.","ErrorValue":null,"TraceCorrelationId":"03ab459e-7076-5000-c1a7-196f1fc54384","ErrorCode":-2147024891,"ErrorTypeName":"System.UnauthorizedAccessException" },"TraceCorrelationId":"03ab459e-7076-5000-c1a7-196f1fc54384" } ]
当我到达 ErrorInfo
时,我只想将其作为字符串而不是解析出来。我不想解析每一块。
代码如下:
try (InputStream is = (InputStream)response.getEntity();
InputStreamReader inputStreamReader = new InputStreamReader(is);
JsonReader jsonReader = new JsonReader(inputStreamReader)) {
if (jsonReader.peek() != JsonToken.BEGIN_ARRAY) {
return;
}
jsonReader.beginArray();
while (jsonReader.hasNext()) {
jsonReader.beginObject(); // Start of the default object on every request
jsonReader.skipValue(); // name SchemaVersion
jsonReader.skipValue(); // value
jsonReader.skipValue(); // name LibraryVersion
jsonReader.skipValue(); // value
jsonReader.skipValue(); // name ErrorInfo
if (jsonReader.peek() == JsonToken.BEGIN_OBJECT) {
// I want to dump the upcoming object to string here
...
是否可以转储给定开始对象的 json reader 的内容,直到它结束为字符串?
类似问题,但不完全相同:Get a dump of a section (object) of JSON
特别感谢https://whosebug.com/users/3389828/nikhil在评论中的回答。对于这种确切情况,您可以使用 Gson.fromJson(jsonReader, Map.class)
。
Gson gson = new Gson();
try (InputStream is = (InputStream)response.getEntity();
InputStreamReader inputStreamReader = new InputStreamReader(is);
JsonReader jsonReader = new JsonReader(inputStreamReader)) {
if (jsonReader.peek() != JsonToken.BEGIN_ARRAY) {
return;
}
jsonReader.beginArray();
while (jsonReader.hasNext()) {
Map header = gson.fromJson(jsonReader, Map.class);
if (header.get("ErrorInfo") != null) {
String errorDump = ((Map)header.get("ErrorInfo")).toString();
// Now I have the error dump I need but I also
// didn't load the entire thing into memory!
...
更多信息:https://javadeveloperzone.com/java-8/java-parse-large-json-file-gson-example/