ZipEntry在Zipfile关闭后仍然存在吗?

2022-08-11 00:00:00 zipfile java inputstream
我当前在我的库中有一个看似合理的资源泄漏,这是因为我打开了一个zipfile文件,因此返回的某个ZipEntry的InputStream不会关闭。然而,关闭返回的InputStream并不会关闭Zipfile的其余部分,因此我只能让它保持打开状态。有没有办法安全地关闭Zipfile并保留InputStream以供返回?


解决方案

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();

注意对#ensureOpenOrZipException的调用。

很遗憾,您的问题的答案是否定的,无法保持流的打开状态。

您可以做的是包装并挂钩InputStream上的#Close以关闭您的压缩文件:

InputStream zipInputStream = ...
return new InputStream() {
    @Override
    public int read() throws IOException {
        return zipInputStream.read();
    }
    @Override
    public void close() throws IOException {
        zipInputStream.close();
        zipFile.close();
    }
}

另一种方法是缓冲它:

InputStream myZipInputStream = ...
//Read the zip input stream fully into memory
byte[] buffer = ByteStreams.toByteArray(zipInputStream);
zipFile.close();
return new ByteArrayInputStream(buffer);

显然,这些数据现在都已进入内存,因此您的数据需要具有合理的大小。

相关文章