Suggerisco di dare un'occhiata a Jackson Api è molto facile combinare le opzioni di analisi dello streaming e del modello ad albero: è possibile spostarsi nel file nel suo complesso in modo streaming e quindi leggere singoli oggetti in un albero struttura.
Come example, prendiamo il seguente testo:
{
"records": [
{"field1": "aaaaa", "bbbb": "ccccc"},
{"field2": "aaa", "bbb": "ccc"}
] ,
"special message": "hello, world!"
}
Provate a immaginare i campi di essere sparsa o le registrazioni avere una struttura più complessa.
Il seguente frammento illustra come questo file può essere letto utilizzando una combinazione di analisi del flusso e del modello ad albero. Ogni singolo record viene letto in una struttura ad albero, ma il file non viene mai letto nella sua interezza nella memoria, rendendo possibile elaborare dimensioni di gigabyte di file JSON mentre si utilizza una memoria minima.
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();
}
}
}
}
Come si può intuire, il nextToken() chiamare ogni volta che dà il prossimo evento di analisi: iniziare oggetto, avviare campo, iniziare a matrice, avviare oggetto, ..., oggetto end, ..., un array end , ...
La chiamata jp.readValueAsTree()
consente di leggere ciò che è nella posizione di analisi corrente, un oggetto o array JSON, nel modello di albero JSON generico di Jackson. Una volta ottenuto questo, è possibile accedere ai dati in modo casuale, indipendentemente dall'ordine in cui le cose appaiono nel file (nel campo di esempio 1 e nel campo 2 non sono sempre nello stesso ordine). Jackson supporta anche la mappatura sui propri oggetti Java. Il jp.skipChildren() è comodo: permette di saltare un albero di oggetti completo o un array senza doverti eseguire su tutti gli eventi in esso contenuti.
Un'alternativa Java EE: javax.json.stream.JsonParser – xonya