15

commons 圧縮ライブラリを使用してディレクトリの tar.gz を作成する際に問題が発生しています。次のようなディレクトリ構造があります。

parent/
    child/
        file1.raw
        fileN.raw

次のコードを使用して圧縮を行っています。例外なく問題なく動作します。しかし、その tar.gz を解凍しようとすると、「childDirToCompress」という名前の単一のファイルが取得されます。正しいサイズであるため、tar プロセスでファイルが互いに明確に追加されています。望ましい出力はディレクトリです。何が間違っているのかわかりません。賢明なコモンズコンプレッサーで正しいパスを設定できますか?

CreateTarGZ() throws CompressorException, FileNotFoundException, ArchiveException, IOException {
            File f = new File("parent");
            File f2 = new File("parent/childDirToCompress");

            File outFile = new File(f2.getAbsolutePath() + ".tar.gz");
            if(!outFile.exists()){
                outFile.createNewFile();
            }
            FileOutputStream fos = new FileOutputStream(outFile);

            TarArchiveOutputStream taos = new TarArchiveOutputStream(new GZIPOutputStream(new BufferedOutputStream(fos)));
            taos.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_STAR); 
            taos.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
            addFilesToCompression(taos, f2, ".");
            taos.close();

        }

        private static void addFilesToCompression(TarArchiveOutputStream taos, File file, String dir) throws IOException{
            taos.putArchiveEntry(new TarArchiveEntry(file, dir));

            if (file.isFile()) {
                BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
                IOUtils.copy(bis, taos);
                taos.closeArchiveEntry();
                bis.close();
            }

            else if(file.isDirectory()) {
                taos.closeArchiveEntry();
                for (File childFile : file.listFiles()) {
                    addFilesToCompression(taos, childFile, file.getName());

                }
            }
        }
4

6 に答える 6

14

私はこのソリューションに従いましたが、より大きなファイルセットを処理するまで機能し、15000 - 16000 ファイルを処理した後にランダムにクラッシュしました。次の行は、ファイル ハンドラをリークしています。

IOUtils.copy(new FileInputStream(f), tOut);

また、OS レベルで「Too many open files」エラーでコードがクラッシュしました。次の小さな変更により、問題が修正されました。

FileInputStream in = new FileInputStream(f);
IOUtils.copy(in, tOut);
in.close();
于 2014-05-07T18:01:16.700 に答える
13

何がうまくいかなかったのか正確にはわかりませんが、Googleキャッシュを精査して実用的な例を見つけました。タンブルウィードでごめんなさい!

public void CreateTarGZ()
    throws FileNotFoundException, IOException
{
    try {
        System.out.println(new File(".").getAbsolutePath());
        dirPath = "parent/childDirToCompress/";
        tarGzPath = "archive.tar.gz";
        fOut = new FileOutputStream(new File(tarGzPath));
        bOut = new BufferedOutputStream(fOut);
        gzOut = new GzipCompressorOutputStream(bOut);
        tOut = new TarArchiveOutputStream(gzOut);
        addFileToTarGz(tOut, dirPath, "");
    } finally {
        tOut.finish();
        tOut.close();
        gzOut.close();
        bOut.close();
        fOut.close();
    }
}

private void addFileToTarGz(TarArchiveOutputStream tOut, String path, String base)
    throws IOException
{
    File f = new File(path);
    System.out.println(f.exists());
    String entryName = base + f.getName();
    TarArchiveEntry tarEntry = new TarArchiveEntry(f, entryName);
    tOut.putArchiveEntry(tarEntry);

    if (f.isFile()) {
        IOUtils.copy(new FileInputStream(f), tOut);
        tOut.closeArchiveEntry();
    } else {
        tOut.closeArchiveEntry();
        File[] children = f.listFiles();
        if (children != null) {
            for (File child : children) {
                System.out.println(child.getName());
                addFileToTarGz(tOut, child.getAbsolutePath(), entryName + "/");
            }
        }
    }
}
于 2012-11-20T15:42:31.683 に答える