【发布时间】:2014-06-17 22:37:24
【问题描述】:
我的库中目前有一个看似合理的资源泄漏,因为我打开了一个 ZipFile,因此某个 ZipEntry 的返回 InputStream 没有关闭。但是,关闭返回的 InputStream 并不会关闭 ZipFile 的其余部分,所以我坚持让它保持打开状态。有没有办法安全地关闭 ZipFile 并保留 InputStream 以供返回?
【问题讨论】:
标签: java inputstream zipfile
我的库中目前有一个看似合理的资源泄漏,因为我打开了一个 ZipFile,因此某个 ZipEntry 的返回 InputStream 没有关闭。但是,关闭返回的 InputStream 并不会关闭 ZipFile 的其余部分,所以我坚持让它保持打开状态。有没有办法安全地关闭 ZipFile 并保留 InputStream 以供返回?
【问题讨论】:
标签: java inputstream zipfile
这里是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 以关闭您的 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);
显然,这一切现在都已进入内存,因此您的数据需要有一个合理的大小。
【讨论】:
getInputStream返回的只是一个InputStream,我还以为是更具体的。那么这不是黑客攻击!
BufferedInputStream。 (即使他们不这样做,他们也希望打开 ZipFile 而不是常规文件)。