java - 在单个 ZipOutputStream 中使用 ObjectOutputStream 写入多个 ZipEntry

标签 java serialization io

我想在 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”中,在将其提供给 对象输出流。然而,这似乎很老套,我想知道我是否错过了 API 中更好的解决方案。

最佳答案

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

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

关于java - 在单个 ZipOutputStream 中使用 ObjectOutputStream 写入多个 ZipEntry,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15907105/

相关文章:

java - 中位数算法的中位数不能始终如一地工作

java - TIMED_WAITING 线程标记为可运行

c++ - 逗号分隔的流到结构中

c++ - 如何(重新)在文件中间写入字节?

java - Maven 解析依赖项的版本

java - 连接到 web 服务导致 com.sun.xml.internal.ws.client.ClientTransportException : The server sent HTTP status code 200: OK

c# - json.net 列表序列化到 JSON 数组

Java JSON 库支持在没有模式的情况下获取和设置深层值吗?

java - 将图像(与 Swing 兼容)从 Java 序列化到 Android 的最佳方法是什么?

java - 如何获得与网格布局内联的 jpg