Ich gebe also Dateidaten an eine API weiter, die ein Reader
benötigt, und ich möchte eine Möglichkeit, den Fortschritt zu melden.
Es scheint einfach zu sein, eine FilterInputStream
-Implementierung zu schreiben, die FileInputStream
umschließt, die Anzahl der gelesenen Bytes im Vergleich zur gesamten Dateigröße verfolgt und ein Ereignis auslöst (oder einige% co_de aufruft) % Methode), um den fraktionellen Fortschritt zu melden.
(Alternativ könnte es absolute Bytes lesen, und jemand anders könnte die Mathematik machen - vielleicht allgemeiner nützlich im Fall von anderen Streaming-Situationen.)
Ich weiß, dass ich das schon einmal gesehen habe und vielleicht habe ich es schon einmal gemacht, aber ich kann den Code nicht finden und bin faul. Hat es jemand herumliegen? Oder kann jemand einen besseren Ansatz vorschlagen?
Ein Jahr (und ein bisschen) später ...
Ich habe eine Lösung implementiert, die auf der Antwort von Adamski basiert, und es hat funktioniert, aber nach einigen Monaten der Nutzung würde ich es nicht empfehlen. Wenn Sie viele Updates haben, wird das Abfeuern / Behandeln unnötiger Fortschrittsereignisse zu hohen Kosten. Der grundlegende Zählmechanismus ist in Ordnung, aber viel besser, wer sich um die Fortschrittsumfrage kümmert, anstatt ihn dazu zu drängen.
(Wenn Sie die Gesamtgröße kennen, können Sie versuchen, ein Ereignis nur bei jeder Änderung von 1% auszulösen, aber es lohnt sich nicht wirklich. Und oft nicht.)
Hier ist eine ziemlich einfache Implementierung, die PropertyChangeEvent
s auslöst, wenn zusätzliche Bytes gelesen werden. Einige Einschränkungen:
mark
oder reset
, obwohl diese einfach hinzuzufügen wären. Code:
%Vor% Guava 's com.google.common.io
-Paket kann Ihnen ein wenig helfen. Das Folgende ist nicht kompiliert und nicht getestet, aber sollte Sie auf den richtigen Weg bringen.
Das sieht nach einer Menge Code aus, aber ich glaube, es ist das Mindeste, womit Sie davonkommen. (Beachten Sie, dass andere Antworten auf diese Frage keine vollständigen Codebeispiele enthalten. Daher ist es schwierig, sie auf diese Weise zu vergleichen.)
Die Antwort von Adamski funktioniert, aber es gibt einen kleinen Fehler. Die überschriebene Methode read(byte[] b)
ruft die Methode read(byte[] b, int off, int len)
über die Superklasse auf.
So wird updateProgress(long numBytesRead)
zweimal für jede Leseaktion aufgerufen, und Sie erhalten am Ende eine numBytesRead
, die doppelt so groß ist wie die Datei, nachdem die gesamte Datei gelesen wurde.
Das Überschreiben der read(byte[] b)
-Methode löst das Problem nicht.
Wenn Sie eine GUI-Anwendung erstellen, gibt es immer ProgressMonitorInputStream . Wenn es keine GUI gibt, die ein InputStream
in der Weise umschließt, wie du es beschreibst, ist es ein Kinderspiel und benötigt weniger Zeit als eine Frage hier zu posten.
Um die Antwort von @Kevin Bourillion zu vervollständigen, kann sie auch mit dieser Technik auf einen Netzwerkinhalt angewendet werden (der verhindert, dass der Stream zweimal gelesen wird: einer für die Größe und einer für den Inhalt):
%Vor%Wo ProgressByteProcessor eine innere Klasse ist:
%Vor%Tags und Links java java-io inputstream