如何解决java.util.zip.ZipFile解压后被java占用问题

 更新时间:2024年06月14日 09:31:07   作者:幸运_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();
}
}
}
  }
  }

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

最新评论