I am reading a nested zip file (a zip file containing multiple other zip files) in memory with the following code
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();
}
The code works fine, but I get StrictMode violation errors (in Android) since the nested Stream nestedZis
is not closed properly.
The problems:
zis.getNextEntry()
before in order to position the outer stream correctlyIs there a solution that handles the resources correctly?
Note I am explicitly not asking about chained streams as described here. I cannot include the nested stream in the try-with-resources statement because of the first problem mentioned above.
Note I can not use ZipFile
since I can only get an Inputstream as my initial resource and do not have access to the File.
Thanks to the tip from @k314159 to use Apache's CloseShieldInputStream
which is part of Apache Commons IO library I changed my code to:
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();
}
This preserves the functionality of my code while also passing Android's StrictMode verifications.
The CloseShieldInputStream
is a proxy stream that prevents the underlying input stream from being closed.
Note There also is a CloseShieldOutputStream
which I now use for the generating of the nested zip.