私は知っているかと思いますが、誰がJavaの大きなファイルを圧縮したいのですか?完全に不合理です。現時点では不信を停止し、大きなzipファイルを解凍する正当な理由があると仮定します。ZipFileを使わずに圧縮ファイルに無作為にアクセスする(ZipFileに大きなバグがあるので)
問題1:ZipFileはbug (bug # 6280693)ですが、sunはこれをJava 1.6(Mustang)で修正しました。この修正は、ソフトウェアがJava 1.4をサポートする必要があるため役に立ちません。バグは、私が理解しているように、このように動作します。次のコードを実行すると、Javaはファイル全体を保持するのに十分な大きさのメモリを割り当てます。
ZipFile zipFile = new ZipFile("/tmp/myFile.zip");
/tmp/myFile.zipが4GBの場合、javaは4GBを割り当てます。これにより、ヒープ例外が発生します。 + 4GBのヒープサイズは残念ながら許容できる解決策ではありません。 =(1を発行する
解決策:使用ZipInputStream、ストリームとしてファイルを扱うため、メモリフットプリントを削減し、制御するため
byte[] buf = new byte[1024];
FileInputStream fs = new FileInputStream("/tmp/myFile.zip")
ZipInputStream zipIn = new ZipInputStream(fs);
ZipEntry ze = zipIn.getNextEntry();
while (ze != null){
while ((int cr = zipIn.read(buf, 0, 1024)) > -1)
System.out.write(buf, 0, len);
ze = zipIn.getNextEntry();
}
問題2:私はZipEntriesランダムアクセスが好きだろうと。私はストリーム全体を検索しなくても、1のZipEntryを解凍したいと思い、ある現在、私はzipEntriesのリストを構築しています、ZESと呼ばれる:。
ZipInputStream zin = new ZipInputStream("/tmp/myFile.zip");
ZipEntry ze = zin.getNextEntry();
List<ZipEntry> zes = new ArrayList<ZipEntry>();
while(ze!=null){
zes.add(ze);
ze = zin.getNextEntry();
}
その後、私は特定のZipEntry Iを解凍する必要がある場合すべてのziを通して反復する一致するzipEntryが見つかるまでpEntryを実行してから圧縮します。
ZipEntry ze = in.getNextEntry();
while (! ze.getName().equals(queryZe.getName())){
ze = zin.getNextEntry();
}
int cr;
while ((cr = zin.read(buf)) > -1)
System.out.write(buf, 0, cr);
Quertion:ZipFileには、ZipEntriesにランダムにアクセスする機能があります。
new BufferedInputStream(zipFile.getInputStream(zipEntry));
ZipFileを使用せずにこの同じ機能を使用するにはどうすればよいですか?
ZipInputStreamには、むしろstrangebehaviorというものがあります。 Javaとします。ZipFiles上
特に良好なドキュメントはここで見つけることができます:
- 日の:
http://commons.apache.org/compress/zip.html
ノートの回答で提案されているとしてApache CommonsのZIPファイルで日ZIPファイルを置き換える切り替えにZipFile.entries()は常にZipEntriesをファイル内の順序で返しますが、apacheコモンZipFile.getEntries()はランダムにエントリを返しますオーダー。これは面白いバグを引き起こしました。これは、エントリが「順番に」あると想定していたコードがあるためです。
あなたの答えはうまくいった、ありがとう! –