我想在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/

10-09 20:43