InputStream oder Reader-Wrapper für Fortschrittsberichte

8

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.)

    
David Moles 27.08.2009, 07:39
quelle

5 Antworten

11

Hier ist eine ziemlich einfache Implementierung, die PropertyChangeEvent s auslöst, wenn zusätzliche Bytes gelesen werden. Einige Einschränkungen:

  • Die Klasse unterstützt keine Operationen mark oder reset , obwohl diese einfach hinzuzufügen wären.
  • Die Klasse prüft nicht, ob die Gesamtzahl der gelesenen Bytes die maximale Anzahl der erwarteten Bytes überschreitet, obwohl dies beim Anzeigen des Fortschritts immer vom Client-Code berücksichtigt werden kann.
  • Ich habe den Code nicht getestet.

Code:

%Vor%     
Adamski 27.08.2009, 08:14
quelle
5

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.

%Vor%

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.)

    
Kevin Bourrillion 25.05.2010 20:42
quelle
3

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.

    
WillamS 10.12.2010 14:13
quelle
1

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.

    
Bombe 27.08.2009 07:49
quelle
0

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%     
Snicolas 11.10.2012 13:58
quelle

Tags und Links