java - 如何在 Java 中使用 Commons compress 解压后删除 ZIP 存档?

标签 java apache-commons-compress

我编写了一个程序,可以解压缩 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 存档,这看起来有点奇怪。

最佳答案

不幸的是,属于您刚刚关闭的流的文件在 Windows 上无法删除是很常见的。有时您需要等待一会儿,有时甚至还不够,您需要一个垃圾收集周期。

例如,这导致了 Ant 的 FileUtils#tryHardToDelete https://github.com/apache/ant/blob/master/src/main/org/apache/tools/ant/util/FileUtils.java#L1569 - 即使这样有时也会使文件悬空,在这种情况下 File#deleteOnExec 是您最好的选择。

关于java - 如何在 Java 中使用 Commons compress 解压后删除 ZIP 存档?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14675317/

相关文章:

java - 如何在java中设置IBM MQ GET预读MaximumSize

java - 无需解压即可预览 .7z 内容和子文件夹

java - Apache 常见压缩在包含到 Android 项目时给出奇怪的错误

java - 具有多个位置的 Spring 属性占位符配置器中的属性解析顺序是什么?

java - 无法在 JasperReports 中使用子报表

java - 在 Hibernate 继承映射策略中绕过 "Table per Concrete Class"

java - 如何检查 TarArchiveEntry 是否设置了 3 个执行位中的任何一个?

java - 如何将 ArchiveEntry 转换为 InputStream?

java - Apache Commons 压缩 : Opening . tar.gz

java - 如何重写compareto方法来订购员工的工资?