Robustes Überspringen von Daten in einem java.io.InputStream und seinen Subtypen

8

Ich verarbeite einen binären Stream und muss effizient eine Reihe von Daten überspringen, die mich nicht interessieren, und einige Daten, die verarbeitet werden.

InputStream.skip(long) macht nicht viel Garantien:

  

Überspringt n Bytes von Daten aus diesem Eingabestrom und verwirft sie. Das Überspringverfahren kann aus einer Vielzahl von Gründen dazu führen, dass eine kleinere Anzahl von Bytes, möglicherweise 0, übersprungen wird. Dies kann aus einer beliebigen Anzahl von Bedingungen resultieren; Das Erreichen des Dateiendes, bevor n Bytes übersprungen wurden, ist nur eine Möglichkeit. Die tatsächliche Anzahl der übersprungenen Bytes wird zurückgegeben.

Ich muss wissen, dass eines von zwei Dingen passiert ist:

  1. Der Stream wurde beendet
  2. Die Bytes wurden übersprungen

Einfach genug. Die in dieser Beschreibung gewährte Nachsicht bedeutet jedoch, dass beispielsweise BufferedInputStream einige Bytes überspringen und zurückgeben kann. Sicher, es sagt mir, dass es nur diese wenigen übersprungen hat, aber es ist nicht klar, warum.

Meine Frage ist also: Können Sie InputStream.skip(long) so benutzen, dass Sie wissen, wann entweder der Stream endet oder der Sprung erfolgreich abgeschlossen wird?

    
Drew Noakes 27.12.2012, 16:18
quelle

2 Antworten

8

Ich glaube nicht, dass wir eine wirklich robuste Implementierung bekommen können, weil der skip() Methodenvertrag ziemlich bizarr ist. Zum einen ist das Verhalten bei EOF nicht gut definiert. Wenn ich 8 Bytes überspringen will und is.skip(8) 0 zurückgibt, ist es nicht trivial zu entscheiden, ob ich es noch einmal versuchen sollte. Es besteht die Gefahr einer Endlosschleife, wenn eine Implementierung 0 bei EOF zurückgibt. available() ist ebenfalls nicht vertrauenswürdig.

Daher schlage ich Folgendes vor:

%Vor%

Sollten wir nicht einen Wert zurückgeben, um die Anzahl der "wirklich übersprungenen" Bytes zu informieren? Oder ein Boolescher Wert, um zu informieren, dass EOF erreicht wurde? Das können wir nicht auf eine robuste Art und Weise tun. Zum Beispiel, wenn wir skip(8) für ein FileInputStream Objekt, es wird 8 zurückgegeben , auch wenn wir sind bei EOF, oder wenn die Datei nur 2 Bytes hat. Aber die Methode ist robust in dem Sinne, dass sie das tut, was wir wollen: n bytes überspringen (wenn möglich) und sie weiter verarbeiten lassen (wenn mein nächster Lesewert -1 zurückkommt, weiß ich, dass EOF erreicht wurde).

    
leonbloy 18.01.2013, 14:26
quelle
2

Dies scheint zu funktionieren, um n bytes zu überspringen:

%Vor%

Es ist jedoch nicht klar, dass es für alle Implementierungen von InputStream funktioniert, die an meine Bibliothek übergeben werden könnten. Ich frage mich, ob die Implementierung meiner eigenen gepufferten Sprungmethode der richtige Weg ist.

    
Drew Noakes 27.12.2012 16:21
quelle