0

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 アーカイブをロックしていることを示しています。これは少し奇妙に思えます。

4

1 に答える 1

3

残念ながら、今閉じたストリームに属するファイルを Windows で削除できないことはよくあることです。少し待つ必要がある場合もあれば、それだけでは不十分でガベージ コレクション サイクルが必要な場合もあります。

たとえば、これは Ant のFileUtils#tryHardToDelete https://github.com/apache/ant/blob/master/src/main/org/apache/tools/ant/util/FileUtils.java#L1569につながっています。ファイルをぶら下げたままにしておくFile#deleteOnExecのが最善の策です。

于 2015-02-14T05:36:44.097 に答える