61

Java では、最初に ZipOutputStream をインスタンス化するか、最初にBufferedOutputStreamインスタンス化するかが重要ですか? 例:

FileOutputStream dest = new FileOutputStream(file);
ZipOutputStream zip = new ZipOutputStream(new BufferedOutputStream(dest));

// use zip output stream to write to

または:

FileOutputStream dest = new FileOutputStream(file);
BufferedOutputStream out = new BufferedOutputStream(new ZipOutputStream(dest));

// use buffered stream to write to

私の非科学的なタイミングでは、ここで多くの違いを見分けることができないようです. Java API には、これらの方法のいずれかが必要かどうか、または優先されるかどうかを示すものは何も表示されません。何かアドバイス?最初に出力を圧縮してから、書き込み用にバッファリングする方が効率的です。

4

2 に答える 2

97

常に を でラップする必要があります。その逆は絶対にしないでくださいBufferedOutputStreamZipOutputStream以下のコードを参照してください。

FileOutputStream fos = new FileOutputStream("hello-world.zip");
BufferedOutputStream bos = new BufferedOutputStream(fos);
ZipOutputStream zos = new ZipOutputStream(bos);

try {
    for (int i = 0; i < 10; i++) {
        // not available on BufferedOutputStream
        zos.putNextEntry(new ZipEntry("hello-world." + i + ".txt"));
        zos.write("Hello World!".getBytes());
        // not available on BufferedOutputStream
        zos.closeEntry();
    }
}
finally {
    zos.close();
}

コメントにあるように、putNextEntry()およびcloseEntry()メソッドは では使用できませんBufferedOutputStream。これらのメソッドを呼び出さないとZipOutputStream、例外がスローされますjava.util.zip.ZipException: no current ZIP entry

完全を期すために、finally 節close()ZipOutputStream. これは、慣例により、すべての組み込み Java 出力ストリーム ラッパー実装がクローズを伝達するためです。

編集

私は逆にそれをテストしました。をラップしてZipOutputStreamから(エントリを作成/クローズせずに)BufferedOutputStream呼び出すだけでは、 . 代わりに、結果の ZIP ファイルは壊れており、その中にエントリはありません。write()ZipException

于 2013-06-19T11:38:05.987 に答える
22

あなたがすべき:

ZipOutputStream out =  new ZipOutputStream(new BufferedOutputStream(dest));

ディスクへの書き込みをバッファリングする必要があるためです (これは、多くの小さなデータ ブロックよりも大きなデータ ブロックの方がはるかに効率的であるためです)。


これ

new BufferedOutputStream(new ZipOutputStream(dest));

zip 圧縮の前にバッファリングします。しかし、これはすべてメモリ内で発生し、バッファリングは必要ありません。小さなメモリ アクセスの多くは、いくつかの大きなメモリ アクセスとほぼ同じ速度だからです。一般にメモリでは、必要な時間は読み取り/書き込みのバイト数に比例します。

コメントで述べたように:

ZipOutputStreamの一部ではないメソッドBufferedOutputStreamも利用できません。例putNextEntrycloseEntry.

于 2013-01-22T15:45:04.863 に答える