如何解决java.util.zip.ZipFile解压后被java占用问题
作者:幸运_syc
这篇文章主要介绍了如何解决java.util.zip.ZipFile解压后被java占用问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
java.util.zip.ZipFile解压后被java占用
在使用jdk自带zip解压工具解压文件时,调用ZipFile的getInputStream(ZipEntry entry)方法获取实体输入流后,正常关闭getInputStram返回的输入流。
zip文件仍然被占用,导致java删除zip文件失败的问题。
解决方法
在解压完成后调用ZipFile的close()方法关闭所有已打开的输入流。
原因:根据源码(jdk1.6)
若压缩方式为STORED,则 getInputStream返回ZipFileInputStream类的输入流
该输入流的close()方法如下:
public void close() {
rem = 0;
synchronized (ZipFile.this) {
if (jzentry != 0 && ZipFile.this.jzfile != 0) {
freeEntry(ZipFile.this.jzfile, jzentry);
jzentry = 0;
}
}
}
// freeEntry releases the C jzentry struct.
private static native void freeEntry(long jzfile, long jzentry);若压缩方式为DEFLATED,则 getInputStream返回InflaterInputStream类的输入流
该输入流的close()方法如下:
protected Inflater inf;
/**
* Closes this input stream and releases any system resources associated
* with the stream.
* @exception IOException if an I/O error has occurred
*/
public void close() throws IOException {
if (!closed) {
if (usesDefaultInflater)
inf.end();
in.close();
closed = true;
}
}
public void end() {
synchronized (zsRef) {
long addr = zsRef.address();
zsRef.clear();
if (addr != 0) {
end(addr);
buf = null;
}
}
}
public class Inflater {
private native static void end(long addr);
}而ZipFile类提供的close()方法为:
主要区别应该在于Store的压缩方式,执行了closeRequested = true 和close(zf),而 ZipFileInputStream只是调用了 freeEntry;
对于 压缩方式为DEFLATED的情况,还未测试。
/**
* Closes the ZIP file.
* <p> Closing this ZIP file will close all of the input streams
* previously returned by invocations of the {@link #getInputStream
* getInputStream} method.
*
* @throws IOException if an I/O error has occurred
*/
public void close() throws IOException {
synchronized (this) {
closeRequested = true;
if (jzfile != 0) {
// Close the zip file
long zf = this.jzfile;
jzfile = 0;
close(zf);
// Release inflaters
synchronized (inflaters) {
int size = inflaters.size();
for (int i = 0; i < size; i++) {
Inflater inf = (Inflater)inflaters.get(i);
inf.end();
}
}
}
}
}总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
