2016-07-31 31 views
-3

Ich verwende eine HTTP-Bibliothek, um Daten abzurufen, die 200 MB groß ist. Jede Zeile in den Daten wird dann verarbeitet. Um Speicher zu sparen, möchte ich die Daten Zeile für Zeile verarbeiten, während die Daten gestreamt werden, anstatt darauf zu warten, dass alle 200 MB zuerst heruntergeladen werden.Unbounded PipedInputStream in Java

Die http Bibliothek ich verwende stellt eine Methode, die so etwas wie OnCharReceived (CharBuffer Puffer) sieht, die so außer Kraft gesetzt werden kann, dass ich jeden Teil der Daten in der Tat Prozess kann, wie es kommt.

Ich möchte diese Daten als InputStream verfügbar machen. Mein erster Gedanke war, ein PipedInputStream- und PipedOutputStream-Paar zu verwenden, wobei ich in OnCharReceived() in PipedOutputStream schreiben und in meinem Thread vom PipedInputStream lesen würde. Dies scheint jedoch das Problem zu haben, dass der zugrunde liegende Puffer der Pipe voll werden könnte, so dass der Schreib-Thread in OnCharReceived blockiert werden müsste, bis mein Thread mit der Verarbeitung der Daten fertig ist. Das Blockieren in OnCharReceived würde jedoch wahrscheinlich im IO-Thread der HTTP-Bibliothek blockieren und wäre sehr schlecht.

Gibt es Java-Klassen da draußen, die das abstrakte Problem lösen, das ich hier lösen muss, ohne dass ich meine eigene Implementierung implementieren muss? Ich kenne Dinge wie BlockingQueue, die als Teil einer größeren Lösung verwendet werden könnten. Aber gibt es irgendwelche einfachen Lösungen?

Aus Gründen der Legacy-Code brauche ich wirklich die Daten als InputStream ausgesetzt.

Edit: Um genauer zu sein ich meinen Code von der Asynchron-Bibliothek Apache HTTP

https://hc.apache.org/httpcomponents-asyncclient-dev/httpasyncclient/examples/org/apache/http/examples/nio/client/AsyncClientHttpExchangeStreaming.java

+2

Sie machen einen Berg aus einem Maulwurfshügel. Verwenden Sie einfach 'URL.openStream()' oder was auch immer es in Ihrer Bibliothek ist, wenn Sie diese Bibliothek wirklich benutzen müssen. Wenn Sie einen Rückruf verwenden und versuchen, * back * in einen Stream für die Verwendung durch einen anderen Thread umzuwandeln, verschwenden Sie nur Zeit und Speicherplatz. – EJP

+0

@EJP eine kleine Bibliothek kann gerechtfertigt werden, wenn es Entschlüsselungsfragen angeht, zum Beispiel in diesem Fall würde er mit welcher API diese Bibliothek bietet integrieren müssen – Dici

+0

Re Ihre "bearbeiten, um genau zu sein", sollten Sie nicht so etwas tun . Diese Bibliothek legt bereits einen 'InputStream' offen. Benutze es. – EJP

Antwort

1

Wenn es eine einfachere Lösung auf das folgende Beispiel bin stützen würde ich nicht in der Nähe von Piped[In/Out]putStream bekommen. Es führt unnötige komplizierte Threading-Bedenken ein, wie Sie darauf hingewiesen haben. Denken Sie daran, dass Sie immer in eine temporäre Datei schreiben und dann aus der Datei als InputStream lesen können. Dies hat auch den Vorteil, dass die HTTP-Verbindung so schnell wie möglich geschlossen wird und Timeouts vermieden werden.

Es kann andere Lösungen geben, abhängig von der API, die Sie verwenden, aber ich denke, dass die vorgeschlagene Lösung aus den oben genannten Gründen noch sinnvoll ist.