1

100.000 以上のファイルがあり、それらのほぼ 4GB があります。そのhtmlなので、70〜80%圧縮できます。ファイルの範囲は 200 KB からほぼ 10 MB です。

ファイルをxmlからhtmlに変換するアプリケーションを開発しています。最後に、アプリケーションは html ディレクトリを zip ファイルにアーカイブします。

「copy-maven-plugin」という Maven プラグインを使用しました。このプラグインのドキュメントはとても良く、使いやすかったです。プラグインが使用するアーカイブ機能はデフォルトで「ant zip」ですが、TrueZip を使用するように変更できます。その反対を開梱するため。とにかく、mye モンスター フォルダを両方の方法でパックしようとしました。デフォルトの Ant zip は 43 分、TrueZip は 38 分を使用しました。私の意見では、どちらの方法でも大したことではありません。

次に、コマンドラインで「zip -rアーカイブフォルダー」を使用して同じことを試みましたが、わずか4分しかかかりませんでした。 編集:最近、40分未満でzipを取得できませんでした。たぶん、4分のものが壊れたzipになってしまったのではないかと思います。

だから、この量のファイルを処理することになると、Javaはそれほど良くないのではないかと考えていました。

誰もこの種の問題を知っているか、経験がありますか?

私はおそらく自分で実装することを考えていますが、バイト読み取りサイズを変更することでそれが役立つでしょうか? ZipInputStream/ZipOutputStream を Zip4j で使用して zip ファイルを作成/解凍し、独自のバッファー サイズを使用することで、読み取られるデータのチャンクを制限できることはわかっていますが、試したことはありません。永遠のようにかかるとき、私は見つけるのを待ち続けることができません;-)

昨夜の時点で、maven は zipIt.sh (zip -r ...) で exec を呼び出して妥当な時間内に作業を行いますが、Java に疑いの余地を与えたいと思います。

更新 1 私は testet のさまざまなアプローチを持っています (すべてデフォルトの圧縮レベル):

  1. Java からの zip4j。かかった時間はわずか3分。しかし、ファイルが壊れていました。zip4j はこの量のファイルを処理しないようです。
  2. Ant zip (maven プラグイン経由)。圧縮: 約 980MB。低速:約40分
  3. コマンドラインから tar + xz 。圧縮: 567MB。低速: 63 分。
  4. コマンドラインからzipします。圧縮: 981MB。速度: 40 分
  5. コマンドラインから tar + bz2。圧縮: 602MB。速度: 13 分
  6. コマンドラインから tar + gz 。圧縮: 864MB。速度: 5 分
  7. java.util.zip.ZipOutputStream. 圧縮: 986MB。速度: 燃える 4 分 18 秒

tar+bz2 と tar+gz はどちらも優れた代替手段のようで、圧縮するか速度を優先するかの選択肢を与えてくれます。

jdk7.0 ZipOutputStreamをテストしていませんでしたが、解決したようです。私は 64KB (64*1024) の読み込みバッファを使用しましたが、うまく機能しているようです。結局、私はJavaで金を打ったようです:-)

これは私の実装です

public static void main(String [] args) {
    String outputFile = Config.getProperty(Property.ZIP_FILE);
    String folderToAdd = Config.getProperty(Property.HTML_FOLDER);
    Zipper.zip(outputFile, folderToAdd, 64*1024);
}

private static void zip(String zipFile, String sourceDirectory, int readChunk) {

    ZipOutputStream out = null;
    try {

        //create byte buffer
        byte[] buffer = new byte[readChunk];

        File dirObj = new File(sourceDirectory);
        out = new ZipOutputStream(new FileOutputStream(zipFile));
        logger.info("Creating zip {} with read buffer '{}'", zipFile, readChunk);
        addDir(dirObj, out, buffer);

    } catch (IOException ioe) {
        logger.error("IOException :" + ioe);
    } finally {
        IOUtils.closeQuietly(out);
    }

}

private static void addDir(File dirObj, ZipOutputStream out, byte [] readChunk) throws IOException {
    logger.debug("Zipping folder '{}'", dirObj.getName());
    StopWatch watch = new StopWatch();
    watch.start();

    File[] files = dirObj.listFiles();

    for (File file : files != null ? files : new File[0]) {
        if (file.isDirectory()) {
            addDir(file, out, readChunk);
            continue;
        }
        FileInputStream in = null;
        try {
            in = new FileInputStream(file.getAbsolutePath());
            out.putNextEntry(new ZipEntry(file.getAbsolutePath()));
            int len;
            while ((len = in.read(readChunk)) > 0) {
                out.write(readChunk, 0, len);
            }

        } finally {
            out.closeEntry();
            IOUtils.closeQuietly(in);
        }
    }
    watch.stop();
    logger.debug("Zipped folder {} in {} seconds.", dirObj.getName(), watch);
}
4

1 に答える 1

1

問題はファイル数自体にあるのではないかと思います。すべてのエントリをアンパックして再パックしなくても、ZIP エントリを操作できる必要があります。これにより、大きな違いが生じる可能性があります。約10倍の違いがあると予想しています。これはJavaで行うことができますが、ほとんどのライブラリはこれ用に設計されていないと思います.

あなたができることはzip、これがあなたが望むことをするように見える場合、Javaから呼び出すことです。コマンド ライン ツールを使用する多数の Maven プラグイン (特にバージョン管理用のもの)

ところで、tar + bz2 などを使用すると、圧縮率が向上する場合があります。これは、各ファイルを個別に圧縮するのではなく、アーカイブ全体を圧縮することでさらに圧縮します。全体を解凍/再圧縮しないと触れられないことを意味します。(これを行う可能性のある JAR/ZIP とは異なります)

于 2013-11-04T08:09:46.490 に答える