我会建议看看Jackson Api结合流和树模型解析选项是非常简单的:您可以通过流式传输整个文件,然后将单个对象读入树中结构体。
作为example,我们采取以下输入:
{
"records": [
{"field1": "aaaaa", "bbbb": "ccccc"},
{"field2": "aaa", "bbb": "ccc"}
] ,
"special message": "hello, world!"
}
试想场是稀疏或有更复杂的结构的记录。
以下片段说明了如何使用流和树模型解析的组合来读取此文件。每个单独的记录都以树形结构读取,但文件从未完全读入内存,因此可以在使用最小内存的情况下处理JSON文件的大小。
import org.codehaus.jackson.map.*;
import org.codehaus.jackson.*;
import java.io.File;
public class ParseJsonSample {
public static void main(String[] args) throws Exception {
JsonFactory f = new MappingJsonFactory();
JsonParser jp = f.createJsonParser(new File(args[0]));
JsonToken current;
current = jp.nextToken();
if (current != JsonToken.START_OBJECT) {
System.out.println("Error: root should be object: quiting.");
return;
}
while (jp.nextToken() != JsonToken.END_OBJECT) {
String fieldName = jp.getCurrentName();
// move from field name to field value
current = jp.nextToken();
if (fieldName.equals("records")) {
if (current == JsonToken.START_ARRAY) {
// For each of the records in the array
while (jp.nextToken() != JsonToken.END_ARRAY) {
// read the record into a tree model,
// this moves the parsing position to the end of it
JsonNode node = jp.readValueAsTree();
// And now we have random access to everything in the object
System.out.println("field1: " + node.get("field1").getValueAsText());
System.out.println("field2: " + node.get("field2").getValueAsText());
}
} else {
System.out.println("Error: records should be an array: skipping.");
jp.skipChildren();
}
} else {
System.out.println("Unprocessed property: " + fieldName);
jp.skipChildren();
}
}
}
}
正如您可以猜到,与nextToken()调用每次给人的下一个解析事件:启动对象,启动现场,启动阵列,启动对象,...,结束对象,...,高端磁盘阵列,...
jp.readValueAsTree()调用允许读取当前解析位置(JSON对象或数组)到JSON的通用JSON树模型中。一旦你有了这个,你可以随机地访问数据,而不管文件在文件中出现的顺序(在示例中,field1和field2并不总是以相同的顺序)。杰克逊也支持映射到您自己的Java对象。 jp.skipChildren()很方便:它允许跳过一个完整的对象树或数组,而无需运行其中包含的所有事件。