2016-04-29 9 views
0

Ich habe eine Methode, die einen InputStream Daten im JSON-Format empfängt. Mit Jackson ObjectMapper, ich bin die Lage, die Input in eine JsonNode zu konvertieren, die ich bearbeiten kann, etwa so:Bearbeiten Sie einen Eingabestream und schreiben Sie es als Stream ohne Speichern aller Inhalte in den Speicher zu einem beliebigen Zeitpunkt

JsonNode revisions = mapper.readTree(data); 

Von dort, ich bin in der Lage durch jedes Element zu durchlaufen und meine Änderungen vornehmen. Dabei speichere ich alle Elemente in einer Liste und konvertiere die Liste dann in einen Stream. Ich würde es vorziehen, jedes Element einzeln aus InputStream zu bearbeiten, so dass ich es nicht alle im Speicher ablegen muss.

Hier ist, was ich habe:

public Stream<Revision> jsonToRevisionObjects(InputStream allData) throws IOException { 
    // convert the InputStream to a JsonNode 
    JsonNode revisions = mapper.readTree(allData); 

    List<Revision> newRevisions = new ArrayList<>(); 
    for (JsonNode revision : revisions.get("results")) { 
     // create Revision objects and add them to newRevisions 
    } 
    return newRevisions.stream(); 
} 

Dies resultierte im Wesentlichen den Punkt sogar mit Strom entzieht, da ich alle neuen Revision Objekte in den Speicher bin zu speichern. Stattdessen würde ich gerne ein Element nach dem anderen lesen und es an den Stream senden, bevor es in das nächste Element geladen wird. Gibt es eine Möglichkeit, dies zu tun? Basierend auf dem umgebenden Code ist der Eingabeparameter immer ein InputStream (da liegt das Problem) und der Rückgabetyp wird immer Stream sein.

könnte dies möglich sein, wenn ich in der Lage war, eine Inputstream in einen Strom und gehen Sie wie folgt zu konvertieren:

return allDataStream.map(rev -> { 
    // create Revision object 
     }); 

aber ich bin nicht sicher, wie zu diesem Zeitpunkt zu erhalten, wenn es eine Möglichkeit ist.

+0

Ich nehme an, dass 'allData' eine Liste von JSON-Objekten ist, ist das korrekt? Ich wundere mich in diesem Fall, wenn es akzeptabel ist, jedes Objekt einzeln in den Speicher zu lesen, anstatt die ganze Liste –

+0

ja, was ich stattdessen tun möchte. Es wäre einfach, wenn die Daten als Stream kommen würden (dann könnte ich einfach map verwenden), aber ich bin mir nicht sicher, was ich tun soll, da es als InputStream kommt. – user2869231

+0

Ich habe die folgende Antwort auf eine ähnliche Frage gefunden kann hilfreich sein http://stackoverflow.com/a/31275144/3529744 –

Antwort

0

Um Streaming-Lesevorgänge zu verwenden, müssen Sie JsonParser entweder direkt oder durch Übergeben an ObjectMapper/ObjectReader verwenden. Wenn ja, können Sie Teilbäume als lesen, wenn Sie möchten.

Zur Konstruktion eines JsonParser aus InputStream ist einfach:

JsonParser p = mapper.getFactory() createParser (input).

aber der Betrieb danach variiert; Sie können den Token-Stream entweder direkt von JsonParser lesen oder ObjectMapper oder ObjectReader anfragen, um den nächsten "Wert" aus dem Stream zu lesen. Und dann ist die Struktur der JSON-Daten wichtig; Möglicherweise müssen Sie den Parser-Stream (nextToken()) weiterleiten, wenn Sie nicht alle Inhalte lesen möchten.

+0

hmm, es wird ein bisschen Arbeit, aber ich werde einige Dinge versuchen. Weißt du, ob es eine Möglichkeit gibt, Stücke von Json auf einmal zu bekommen? Wie in .. Ich habe eine Liste von JSON-Objekten und möchte ein ganzes Objekt auf einmal in diese Liste aufnehmen (sagen wir mal 3 Schlüssel: Wert-Paare). Ich wiederhole eins nach dem anderen mit nextField und nextValue, aber am liebsten würde ich einfach eine ganze Map erstellen. – user2869231

+0

@ user2869231 nicht ganz sicher, ob ich Ihre Frage hier verstanden habe.Jackson muss Teile des zugrunde liegenden JSON-Inhalts dekodieren, um zu wissen, was was ist, und dies wird als 'JsonToken'-Stream exponiert, der mit' JsonParser.nextToken() '(und ähnlichen Methoden) durchsucht werden kann. Damit kannst du alles machen, was du willst. Auf der höheren Ebene "ObjectReader"/"ObjectMapper" sind Ihre Auswahlmöglichkeiten eingeschränkt, da sie Teilbäume lesen. – StaxMan