Anfügen an ein ObjectOutputStream
Ist es nicht möglich, zum Anhängen an ein ObjectOutputStream
?
Ich versuche zum Anhängen an eine Liste von Objekten. Folgende Code ist eine Funktion, die aufgerufen wird, wenn ein Auftrag abgeschlossen ist.
FileOutputStream fos = new FileOutputStream
(preferences.getAppDataLocation() + "history" , true);
ObjectOutputStream out = new ObjectOutputStream(fos);
out.writeObject( new Stuff(stuff) );
out.close();
Aber wenn ich versuche, es zu Lesen, bekomme ich nur die erste in der Datei.
Dann bekomme ich java.io.StreamCorruptedException
.
Zu Lesen, ich bin mit
FileInputStream fis = new FileInputStream
( preferences.getAppDataLocation() + "history");
ObjectInputStream in = new ObjectInputStream(fis);
try{
while(true)
history.add((Stuff) in.readObject());
}catch( Exception e ) {
System.out.println( e.toString() );
}
Ich weiß nicht, wie viele Objekte vorhanden sein, so lese ich, während es gibt keine Ausnahmen. Von dem, was Google sagt, das ist nicht möglich. Ich Frage mich, ob jemand eine Möglichkeit kennt?
Bekommen Sie überhaupt etwas aus dem stream, oder ist es eine Ausnahme das erste mal in der Schleife?
es liest das erste Objekt, das ich gespeichert, dann bekomme ich die exception.
Im code oben, ich bin nur zu sehen, ein Objekt in die Datei geschrieben, also nur eine würde gelesen werden, richtig?
erste Schnipsel ist eine Funktion, die mehrfach aufgerufen wird, wenn ein Auftrag abgeschlossen ist. aber ich kann nur Lesen, die erste, die ich schrieb.
Ihr code hier schreibt nur 1 Objekt auf den stream, ist es etwas, was nicht gezeigt wird, schreibt mehr als 1 Objekt zu streamen ?
es liest das erste Objekt, das ich gespeichert, dann bekomme ich die exception.
Im code oben, ich bin nur zu sehen, ein Objekt in die Datei geschrieben, also nur eine würde gelesen werden, richtig?
erste Schnipsel ist eine Funktion, die mehrfach aufgerufen wird, wenn ein Auftrag abgeschlossen ist. aber ich kann nur Lesen, die erste, die ich schrieb.
Ihr code hier schreibt nur 1 Objekt auf den stream, ist es etwas, was nicht gezeigt wird, schreibt mehr als 1 Objekt zu streamen ?
InformationsquelleAutor Hamza Yerlikaya | 2009-07-28
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hier ist der trick: Unterklasse
ObjectOutputStream
ab und setzen diewriteStreamHeader
Methode:Verwenden, prüfen Sie einfach, ob Sie die history-Datei vorhanden ist oder nicht und instanziieren Sie entweder dieses appendable-stream (falls die Datei vorhanden ist, = wir append = wir wollen keinen header) oder den original-stream (falls die Datei nicht vorhanden ist = wir brauchen ein header).
Bearbeiten
War ich nicht zufrieden mit der ersten Benennung der Klasse. Der hier ist besser: es beschreibt das 'was es ist' eher das 'wie es geht'
Bearbeiten
Haben den Namen geändert, einmal mehr, zu verdeutlichen, dass dieser stream ist nur für das Anhängen an eine bestehende Datei. Es kann nicht verwendet werden, um einen neue - Datei mit Objektdaten.
Bearbeiten
Wurde einen Aufruf
reset()
nach diese Frage zeigten, dass die ursprüngliche version, die nur überschriebwriteStreamHeader
zu einem no-op könnte unter bestimmten Bedingungen einen stream erstellen, der konnte nicht gelesen werden.Danke für deine Kommentare 🙂 ja, ich habe getestet (nur vergessen zu erwähnen es in der Antwort)
+1, danke. Warnung: writeStreamHeader() wird aufgerufen, durch den ObjectOutputStream Konstruktor. Das macht es zumindest schwierig für eine einzelne Klasse zu behandeln beide Fälle. Sie können einen einfachen factory-Methode, liefert fileExists ? neue AppendingObjectOutputStream( out ) : new ObjectOutputStream( out );
Jeder bitte beachten Sie, dass dies ist nur Anhängen um eine - Datei! Ein neuen - Datei erstellt werden, die mit der normalen ObjectOutputStream, denn wir brauchen den header am Anfang der Datei.
anscheinend gibt es ist ein problem mit dieser Lösung, wenn Sie mit ihm hantieren genug. Blick auf diese Frage: stackoverflow.com/questions/12279245/...
InformationsquelleAutor Andreas_D
Als API sagt, die
ObjectOutputStream
Konstruktor schreibt die Serialisierung stream-header an den zugrunde liegenden stream. Und dieser header wird voraussichtlich nur einmal, am Anfang der Datei. So ruftmehrmals auf die
FileOutputStream
bezieht sich auf die gleiche Datei schreiben, die header mehrfach und die Datei ist beschädigt.InformationsquelleAutor Tadeusz Kopec
Da das genaue format der serialisierten Datei anfügen, wird in der Tat korrupt. Schreiben Sie alle Objekte, um die Datei als Teil des gleichen Strom, oder es wird Abstürzen, wenn er liest den stream-Metadaten, wenn er erwartet ein Objekt.
Konnte man Lesen, die Serialisierung Spezifikation für mehr details, oder (einfacher) Lesen dieser thread wo Roedy Green sagt im Grunde das, was ich gerade sagte.
InformationsquelleAutor Michael Myers
Der einfachste Weg, um dieses problem zu vermeiden, ist, halten Sie den Ausgabestrom geöffnet, wenn Sie die schreiben der Daten, sondern schließen Sie es nach jedem Objekt. Aufruf
reset()
könnte sinnvoll sein, um Speicherlecks zu vermeiden.Die alternative wäre, die Datei zu Lesen, als eine Reihe von aufeinander folgenden ObjectInputStreams als gut. Aber dies erfordert, Sie zu zählen, wie viele bytes man Lesen (dies kann implementd mit einem FilterInputStream), dann schließen Sie den InputStream, öffnen Sie es erneut, überspringen viele bytes und nur dann wickeln Sie es in ein ObjectInputStream().
InformationsquelleAutor Michael Borgwardt
Wie vor jedes mal, wenn Sie fügen ein Objekt, Lesen und kopieren alle aktuellen Daten in der Datei und überschreiben Sie dann alle zusammen in eine Datei.
InformationsquelleAutor user4147874