微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何正确关闭嵌套的 ZipInputStreams?

如何解决如何正确关闭嵌套的 ZipInputStreams?

我正在使用以下代码读取一个嵌套的 zip 文件一个包含多个其他 zip 文件的 zip 文件内存

try (ZipInputStream zis = new ZipInputStream(inputStream)) {
   ZipEntry zipEntry;
   while ((zipEntry = zis.getNextEntry()) != null) {
      if (zipEntry.getName().endsWith(".zip")) {
         ZipInputStream nestedZis = new ZipInputStream(zis);
         Pojo myPojo = myPojoReader.readFrom(nestedZis);
      }
   }
   zis.closeEntry();
}

代码工作正常,但由于嵌套流 nestedZis 未正确关闭,我收到了 StrictMode 违规错误(在 Android 中)。

问题:

  1. 我无法提前实例化它,因为我必须先调用 zis.getNextEntry() 才能正确定位外部流
  2. 我无法在 while 循环中关闭它,因为这也会关闭外部 ZipInputStream

是否有正确处理资源的解决方案?

注意我明确没有询问如 here 所述的链式流。由于上面提到的第一个问题,我无法在 try-with-resources 语句中包含嵌套流。

注意我不能使用 ZipFile,因为我只能获得一个 Inputstream 作为我的初始资源并且无法访问文件

解决方法

感谢@k314159 提示使用 Apache 的 CloseShieldInputStream,它是 Apache Commons IO 库的一部分,我将代码更改为:

try (ZipInputStream zis = new ZipInputStream(inputStream)) {
   ZipEntry zipEntry;
   while ((zipEntry = zis.getNextEntry()) != null) {
      if (zipEntry.getName().endsWith(".zip")) {
         try (CloseShieldInputStream cloned = CloseShieldInputStream.wrap(zis); ZipInputStream nestedZis = new ZipInputStream(cloned)) {
            Pojo myPojo = myPojoReader.readFrom(nestedZis);
         }
      }
   }
   zis.closeEntry();
}

这保留了我的代码的功能,同时还通过了 Android 的 StrictMode 验证。

CloseShieldInputStream 是一个代理流,可防止底层输入流被关闭。

注意还有一个 CloseShieldOutputStream,我现在用它来生成嵌套的 zip。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。