我已經編寫了一個解壓縮ZIP壓縮文件的程序,然後遞歸解壓縮或提取壓縮文件中找到的壓縮文件。 ZIP中的檔案可能是tar或ZIP檔案,我可以將它們提取得很好。如何使用Java中的Commons Compress解壓縮後刪除ZIP存檔?
在提取某個新目錄中的內部存檔後,我想刪除它們。這對於tar檔案來說工作得很好,但由於某些原因,它不適用於ZIP檔案。我關閉了所有流,並且應該刪除失敗,我使用deleteOnExit作爲失敗保護,但這也不起作用。
try (ArchiveInputStream ais =
asFactory.createArchiveInputStream(
new BufferedInputStream(
new FileInputStream(archive)))) {
System.out.println("Extracting!");
ArchiveEntry ae;
while ((ae = ais.getNextEntry()) != null) {
if (ae.isDirectory()) {
File dir = new File(archive.getParentFile(), ae.getName());
dir.mkdirs();
continue;
}
File f = new File(archive.getParentFile(), ae.getName());
File parent = f.getParentFile();
parent.mkdirs();
try (OutputStream os = new FileOutputStream(f)) {
IOUtils.copy(ais, os);
os.close();
} catch (IOException innerIoe) {
...
}
}
ais.close();
if (!archive.delete()) {
System.out.printf("Could not remove archive %s%n",
archive.getName());
archive.deleteOnExit();
}
} catch (IOException ioe) {
...
}
應該沒有開放的流,除非關閉ArchiveInputStream不會實際關閉流。但這又適用於tar檔案。
我在某處讀到一個地方,可以刪除調用父文件上的listFiles()並找到ZIP存檔並刪除它的ZIP存檔,但這聽起來像是一個奇怪的複雜過程。必須有一些更簡單的方法。
編輯:
的問題是特定於Windows。在Linux上(SliTaz 4和Red Hat Enterprise 5),這個工作非常好。這告訴我,Windows以某種方式鎖定ZIP檔案,這似乎有點奇怪。
您應該使用'try-finally'語句來確保在發生異常時發生流關閉。 – Vulcan
檢查'.mkdirs()'和朋友,他們可能會自動失敗 - 這就是爲什麼如果使用Java 7而不是'File'則應該使用'Files' API。 – fge
@Vulcan我將它切換到試用資源。但沒有區別。 @fge使用'Files'和'Path',它告訴我該文件正在被另一個進程使用(這可能意味着程序本身)。但即使使用'deleteOnExit'也沒有效果,這讓我覺得該文件可能正在被操作系統使用(我現在正在Windows上運行它,但我明天會在Linux上嘗試它)。如果'mkdirs'失敗或我將其刪除,則在提取時創建的文件上會出現I/O異常。 – Sardtok