2014-06-17 34 views
5

我目前在我的库中有一个合理的资源泄漏,这是因为我保存了一个ZipFile,因此某个ZipEntry的返回InputStream没有关闭。但是,关闭返回的InputStream不会关闭ZipFile的其余部分,所以我一直保持打开状态。有没有办法安全地关闭ZipFile并保持InputStream返回?ZipFile关闭后ZipEntry是否存在?

回答

4

这里是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#关闭关闭您的zip文件:

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

显然,这有现在都进入了记忆,所以你的数据将需要一个合理的大小。

+0

这是一个黑客,但它的作品! –

+0

为什么这是一个黑客?这是zip #close的简单封装。我添加了另一种方法,这是我的第一个想法,但它使用了一个内存缓冲区,它可能不适合你。 – Kong

+0

实际上看代码,我意识到'getInputStream'只返回一个InputStream,我认为它更具体。那就不是黑客! –