2009-05-05 13 views
7

Nachdem ich einige verarbeitete Inhalte in einen Ausgabestream geschrieben habe, muss ich den Anfang des Streams erneut aufrufen und einige Inhaltsmetadaten ausschreiben. Die Daten, die ich schreibe, sind sehr groß, so viel wie 4 GB, und können abhängig von verschiedenen Umweltfaktoren entweder direkt in eine Datei oder in einen Puffer im Speicher geschrieben werden.Wie kann ich einen OutputStream implementieren, den ich zurückspulen kann?

Wie kann ich einen OutputStream implementieren, der es mir ermöglicht, nach dem Schreiben des Inhalts Header zu schreiben?

+0

Es bedauerlicherweise nicht, aber das liegt hauptsächlich daran, dass ich aufgrund anderer Überlegungen mein Design ändern musste. Es ist immer noch eine gute Antwort. –

Antwort

10

Hier ist ein Direktzugriffsdatei-Ausgabestream.

Beachten Sie, dass Sie es für eine große Menge gestreamter Ausgabe vorübergehend in einen BufferedOutputStream umhüllen können, um viele kleine Schreibvorgänge zu vermeiden (seien Sie sehr sicher, es zu leeren, bevor Sie den Wrapper verwerfen oder den zugrunde liegenden Stream direkt verwenden).

2

Wenn Sie die Größe der Kopfzeile wissen, können Sie zunächst eine leere Kopfzeile schreiben, dann gehen Sie zurück, um es mit RandomAccessFile am Ende zu beheben. Wenn Sie die Größe des Headers nicht kennen, haben Sie grundsätzlich die Möglichkeit, dass Dateisysteme das Einfügen von Daten generell nicht zulassen. Sie müssen also in eine temporäre Datei schreiben und dann die echte Datei schreiben.

+0

Wir kennen die Größe des Headers, aber es gibt keine Möglichkeit, einen generischen OuptutStream zu finden, der es erlaubt, an einem beliebigen Punkt im Stream zu schreiben. –

+0

Sie schreiben es aus. Schließen Sie die Datei. Öffnen Sie eine RandomAccessFile. Schreibe die Kopfzeile. Schließen Sie die RandomAccessFile. –

+1

(Beachten Sie, dass RandomAccessFile pro Vorgangsleistung saugt, verwenden Sie also große Blockoperationen.) –

0

Eine Möglichkeit wickeln Anfangsinhalt in einen Speicherpuffer zu schreiben, zuerst, dann Header in ‚echten‘ Ausgabestrom, gefolgt von flush gepufferter Inhalt, und von dort nur in den nicht gepufferten Stream schreiben. Es klingt, als wäre das erste Segment nicht so lang, um die Pufferung vernünftig zu machen. Um es zu implementieren, können Sie ByteArrayOutputStream für das Puffern verwenden und Ihre OutputStream-Klasse dann als Argument "echten" Ausgabestream nehmen lassen; und wechsle einfach zwischen den beiden nach Bedarf. Möglicherweise müssen Sie die OutputStream-API erweitern, um zu definieren, welche Metadaten geschrieben werden sollen, da diese Auslöser aus dem gepufferten Modus wechseln.

Wie von der anderen Antwort erwähnt, würde RandomAccessFile auch funktionieren, obwohl OutputStream nicht implementieren würde.

+1

"Die Daten, die ich schreibe, sind sehr groß, so viel wie 4 GB" – DJClayworth

Verwandte Themen