迭代 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 正在处理流,因此无法自由跳转。这就是为什么它必须读取和解压缩所有 zip 数据才能到达每个条目的 EOF 并读取下一个条目标题。
这是什么意思?如果您的文件系统中已经有一个 zip 文件 - 无论您的任务如何,都使用 ZipFile 来处理它。作为奖励,您可以按顺序或随机访问 zip 条目(性能损失相当小)。另一方面,如果您正在处理流,则需要使用 ZipInputStream 顺序处理所有条目。
这是一个例子。使用 ZipFile 在 0.05 秒内迭代包含三个 0.6Gb 条目的 zip 存档(总文件大小 = 1.6Gb),使用 ZipInputStream 在 18 秒内迭代。