最近在接口调试中遇到,将ftp上xxx.zip文件下载到本地磁盘,将文件解压缩后,文件无法被删除的问题,不论是用java代码,亦或是直接在磁盘上进行删除,都删除不了,总是提示操作无法完成,因为文件夹已在java(TM) Platform SE binary中打开。
造成此问题的根本原因在于该文件的引用没有被释放,所以文件处于被占用的情况。
最初的时候发现io流、out流都已经close了,可是文件还是处于被占用的状态,开始的时候试过将文件的引用置为null,然后手动的调用JVM垃圾回收器System.gc();不过并没有任何效果,经过一级一级的调试,最终发现还是解压缩过程中使用的ZipFile类没有关闭,关闭后,问题就解决了,如果你有遇到类似问题,可以分级调试,看看哪里没有关闭。
下面是我更改过的解压缩方法:
/**
* @param zipFile 解压缩文件
* @param descDir 压缩的目标地址,如:D:\测试 或 /mnt/d/测试
* @return
* @description: 对.zip文件进行解压缩
* @author: nr
* @exception:
* @date: 2019/7/10 13:06
* @version: 1.0
*/
@SuppressWarnings("rawtypes")
public static List<File> upzipFile(File zipFile, String descDir) {
List<File> list = new ArrayList<>();
// 防止文件名中有中文时出错
System.setProperty("sun.zip.encoding", System.getProperty("sun.jnu.encoding"));
try {
if (!zipFile.exists()) {
throw new RuntimeException("解压失败,文件 " + zipFile + " 不存在!");
}
ZipFile zFile = new ZipFile(zipFile, "GBK");
for (Enumeration entries = zFile.getEntries(); entries.hasMoreElements();) {
ZipEntry entry = (ZipEntry) entries.nextElement();
File file = new File(descDir + File.separator + entry.getName());
if (entry.isDirectory()) {
file.mkdirs();
} else {
File parent = file.getParentFile();
if (!parent.exists()) {
parent.mkdirs();
}
InputStream in = zFile.getInputStream(entry);
OutputStream out = new FileOutputStream(file);
IOUtils.copy(in, out);
zFile.close(); //这里没关闭,是我这边的问题所在
in.close();
out.flush();
out.close();
list.add(file);
}
}
} catch (IOException e) {
throw new RuntimeException(e.getMessage());
}
return list;
}