使用ObjectOutputStream写入单个ZipOutputStream中的多个ZipEntrys

Phi*_*ler 5 java io serialization

我想在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
}
Run Code Online (Sandbox Code Playgroud)

我当然知道在完成使用后我应该关闭每个流,所以我应该ObjectOutputStream在指定的位置关闭s.然而,关闭ObjectOutputStreams也将关闭ZipOutputStream我仍然需要的.

我不想省略调用,ObjectOutputStream.close()因为我不想依赖它目前不超过flush()和的事实reset().

我也不能使用单个ObjectOutputStream实例,因为我错过了构造函数编写的流头文件(zip存档中的每个文件都不是完整的对象序列化文件,我无法独立反序列化它们).

再次读取文件时会出现同样的问题.

我看到的唯一方法是将ZipOutputStream某些"CloseProtectionOutputStream" 包装起来,除非close()在将它提供给之前转发所有方法ObjectOutputStream.然而,这似乎相当hacky,我想知道我是否错过了API中更好的解决方案.

oli*_*666 2

如果您的OutputStream包装器在多次关闭时抛出异常,那么这不是黑客行为。您可以为每个 zip 条目创建一个包装器。

从架构的角度来看,我认为ObjectOutputStream作者应该提供禁用级联的选项close()。你只是在解决他缺乏的API。