如何正确关闭嵌套的 ZipInputStreams?
How to correctly close nested 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 中)。
问题:
- 我无法提前实例化它,因为我必须先调用
zis.getNextEntry()
才能正确定位外部流
- 我无法在 while 循环中关闭它,因为那样也会关闭外部 ZipInputStream
是否有正确处理资源的解决方案?
注意 我明确地没有询问 here 中描述的链式流。由于上面提到的第一个问题,我无法在 try-with-resources 语句中包含嵌套流。
注意我不能使用ZipFile
因为我只能得到一个输入流作为我的初始资源并且不能访问文件。
感谢@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。
我正在读取嵌套的 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 中)。
问题:
- 我无法提前实例化它,因为我必须先调用
zis.getNextEntry()
才能正确定位外部流 - 我无法在 while 循环中关闭它,因为那样也会关闭外部 ZipInputStream
是否有正确处理资源的解决方案?
注意 我明确地没有询问 here 中描述的链式流。由于上面提到的第一个问题,我无法在 try-with-resources 语句中包含嵌套流。
注意我不能使用ZipFile
因为我只能得到一个输入流作为我的初始资源并且不能访问文件。
感谢@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。