I currently have a plausible resource leak in my library due to the fact that I hold a ZipFile open so that the returned InputStream for a certain ZipEntry is not closed. However, closing the returned InputStream doesn't close the rest of the ZipFile, so I'm stuck with it left open. Is there a way to safely close the ZipFile and keep the InputStream for returning?
ZipInputStream. close() method closes this input stream and releases any system resources associated with the stream.
extends ZipEntry> entries = zipFile. entries(); Each entry is of type ZipEntry which provides the following methods for reading information of an individual entry (to name a few): getName(): returns the name of the entry in form of a relative path.
Getting a ZipEntry ZipEntry ). To extract a file from the ZIP file you can call the method getEntry() method on the ZipFile class. Here is an example of calling getEntry() : ZipEntry zipEntry = zipFile.
To unzip a zip file, we need to read the zip file with ZipInputStream and then read all the ZipEntry one by one. Then use FileOutputStream to write them to file system. We also need to create the output directory if it doesn't exists and any nested directories present in the zip file.
Here's the implementation of InputStream from ZipFile:
/*
* Inner class implementing the input stream used to read a
* (possibly compressed) zip file entry.
*/
private class ZipFileInputStream extends InputStream {
...
public int read(byte b[], int off, int len) throws IOException {
if (rem == 0) {
return -1;
}
if (len <= 0) {
return 0;
}
if (len > rem) {
len = (int) rem;
}
synchronized (ZipFile.this) {
ensureOpenOrZipException();
Notice the call to #ensureOpenOrZipException
.
So the answer to your question is unfortunately no, there is no way to keep the stream open.
What you could do instead is wrap and hook the #close on the InputStream to close your zip file:
InputStream zipInputStream = ...
return new InputStream() {
@Override
public int read() throws IOException {
return zipInputStream.read();
}
@Override
public void close() throws IOException {
zipInputStream.close();
zipFile.close();
}
}
Another approach would be to buffer it:
InputStream myZipInputStream = ...
//Read the zip input stream fully into memory
byte[] buffer = ByteStreams.toByteArray(zipInputStream);
zipFile.close();
return new ByteArrayInputStream(buffer);
Obviously this has now all gone into memory, so your data will need to be a reasonable size.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With