最近在接口調試中遇到,將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;
}