问题描述
我正在使用以下代码读取一个嵌套的 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 中)。
问题:
是否有正确处理资源的解决方案?
注意我明确没有询问如 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。