Ich möchte ein Zip-Archiv in Java erstellen, wo jede enthaltene Datei durch Serialisierung einiger Objekte erzeugt wird. Ich habe ein Problem beim korrekten Schließen der Streams.Schreiben mit ObjectOutputStream in mehrere ZipEntrys in einem einzigen ZipOutputStream
Der Code sieht wie folgt aus:
try (OutputStream os = new FileOutputStream(file);
ZipOutputStream zos = new ZipOutputStream(os);) {
ZipEntry ze;
ObjectOutputStream oos;
ze = new ZipEntry("file1");
zos.putNextEntry(ze); // start first file in zip archive
oos = new ObjectOutputStream(zos);
oos.writeObject(obj1a);
oos.writeObject(obj1b);
// I want to close oos here without closing zos
zos.closeEntry(); // end first file in zip archive
ze = new ZipEntry("file2");
zos.putNextEntry(ze); // start second file in zip archive
oos = new ObjectOutputStream(zos);
oos.writeObject(obj2a);
oos.writeObject(obj2b);
// And here again
zos.closeEntry(); // end second file in zip archive
}
Ich weiß natürlich, dass ich jeden Strom schließen sollte, nachdem es mit Finishing, also sollte ich die ObjectOutputStream
s in den angegebenen Positionen schließen. Schließen der ObjectOutputStream
s würde aber auch die ZipOutputStream
schließen, die ich noch brauche.
Ich möchte nicht den Anruf an ObjectOutputStream.close()
weglassen, weil ich nicht auf die Tatsache verlassen möchte, dass es derzeit nicht mehr als flush()
und reset()
.
Ich kann auch keine einzige -Instanz verwenden, weil ich dann den Stream-Header vermisse, der vom Konstruktor geschrieben wird (jede einzelne Datei im ZIP-Archiv wäre keine vollständige Objektserialisierungsdatei und ich konnte sie nicht deserialisieren unabhängig).
Das gleiche Problem tritt beim erneuten Lesen der Datei auf.
Der einzige Weg, ich sehe, würde die ZipOutputStream
in einer Art „CloseProtectionOutputStream“ wickeln, die alle Methoden außer close()
weiterleiten, bevor ihm die ObjectOutputStream
geben. Dies scheint jedoch eher hacky und ich frage mich, ob ich eine bessere Lösung in der API verpasst habe.
IMHO das Problem liegt in der ZIP API und nicht in OOS. Anstelle von lustigen Dingen wie 'closeEntry' sollte es Ihnen einen richtigen Ausgabestrom geben, den Sie' schließen' könnten (siehe TrueZip). – maaartinus