zip ファイルを反復処理する正しい方法
final ZipFile file = new ZipFile( FILE_NAME );
try
{
final Enumeration<? extends ZipEntry> entries = file.entries();
while ( entries.hasMoreElements() )
{
final ZipEntry entry = entries.nextElement();
System.out.println( entry.getName() );
//use entry input stream:
readInputStream( file.getInputStream( entry ) )
}
}
finally
{
file.close();
}
private static int readInputStream( final InputStream is ) throws IOException {
final byte[] buf = new byte[ 8192 ];
int read = 0;
int cntRead;
while ( ( cntRead = is.read( buf, 0, buf.length ) ) >=0 )
{
read += cntRead;
}
return read;
}
Zip ファイルは複数のエントリで構成され、各エントリには現在のエントリのバイト数を含むフィールドがあります。そのため、実際のデータを解凍せずに、すべての zip ファイル エントリを簡単に反復できます。java.util.zip.ZipFile はファイル/ファイル名を受け入れ、ランダム アクセスを使用してファイル位置間をジャンプします。一方、java.util.zip.ZipInputStream はストリームを操作しているため、自由にジャンプできません。そのため、各エントリの EOF に到達して次のエントリ ヘッダーを読み取るために、すべての zip データを読み取って解凍する必要があります。
どういう意味ですか?ファイル システムに既に zip ファイルがある場合は、タスクに関係なく、ZipFile を使用して処理します。おまけとして、zip エントリに順次またはランダムにアクセスできます (パフォーマンスの低下はかなり小さくなります)。一方、ストリームを処理している場合は、ZipInputStream を使用してすべてのエントリを順番に処理する必要があります。
ここに例があります。3 つの 0.6Gb エントリを含む zip アーカイブ (合計ファイル サイズ = 1.6Gb) は、ZipFile を使用して 0.05 秒、ZipInputStream を使用して 18 秒で反復されました。