我想在Java中创建一个zip存档,其中每个包含的文件都是通过序列化一些对象而生成的。我有正确关闭流的问题。
代码如下:
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
}
我当然知道应该在使用完每个流之后将其关闭,因此应该在指示的位置关闭
ObjectOutputStream
。但是,关闭ObjectOutputStream
也会关闭我仍然需要的ZipOutputStream
。我不想忽略对
ObjectOutputStream.close()
的调用,因为我不想依赖于它目前不超过flush()
和reset()
的事实。我也不能使用单个
ObjectOutputStream
实例,因为那样我会错过由构造函数编写的流 header (zip归档文件中的每个单个文件都不是完整的对象序列化文件,并且我无法独立地对其进行反序列化)。再次读取文件时,会发生相同的问题。
我看到的唯一方法是将
ZipOutputStream
包装在某种“CloseProtectionOutputStream”中,该类将转发除close()
之外的所有方法,然后再将其提供给ObjectOutputStream
。但是,这似乎很hacky,我想知道我是否错过了API中更好的解决方案。 最佳答案
如果您的OutputStream
包装器在关闭多次后抛出异常,则不是黑客。您可以为每个zip条目创建一个包装器。
从体系结构的角度来看,我认为ObjectOutputStream
作者应该提供了一个选项来禁用close()
级联。您只是在解决他缺少的API。
关于java - 使用ObjectOutputStream在单个ZipOutputStream中写入多个ZipEntry,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15907105/