我编写了一个解压缩ZIP存档的程序,然后递归解压缩或提取其中的档案。 ZIP中的档案可能是tar或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存档,这看起来有点奇怪。
答案 0 :(得分:3)
不幸的是,在Windows上无法删除属于刚刚关闭的流的文件。有时你需要等待一段时间,有时即使这还不够,你需要一个垃圾收集周期。
例如,这导致了Ant的FileUtils#tryHardToDelete
https://github.com/apache/ant/blob/master/src/main/org/apache/tools/ant/util/FileUtils.java#L1569 - 即使知道有时会让文件悬空,在这种情况下File#deleteOnExec
是最好的选择。