如何解决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(); } } } } }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。