我注意到与使用WinZip等本机工具相比,Java中的解压缩工具非常慢.
是否有可用于Java的第三方库更高效?开源是首选.
编辑
这是使用Java内置解决方案vs 7zip的速度比较.我在原始解决方案中添加了缓冲输入/输出流(感谢Jim,这确实产生了很大的不同).
Zip文件大小:800K Java解决方案:2.7秒7Zip解决方案:204毫秒
以下是使用内置Java解压缩的修改代码:
/** Unpacks the give zip file using the built in Java facilities for unzip. */
@SuppressWarnings("unchecked")
public final static void unpack(File zipFile, File rootDir) throws IOException
{
ZipFile zip = new ZipFile(zipFile);
Enumeration<ZipEntry> entries = (Enumeration<ZipEntry>) zip.entries();
while(entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
java.io.File f = new java.io.File(rootDir, entry.getName());
if (entry.isDirectory()) { // if its a directory, create it
continue;
}
if (!f.exists()) {
f.getParentFile().mkdirs();
f.createNewFile();
}
BufferedInputStream bis = new BufferedInputStream(zip.getInputStream(entry)); // get the input stream
BufferedOutputStream bos = new BufferedOutputStream(new java.io.FileOutputStream(f));
while (bis.available() > 0) { // write contents of 'is' to 'fos'
bos.write(bis.read());
}
bos.close();
bis.close();
}
}
Run Code Online (Sandbox Code Playgroud)
mer*_*ike 22
问题不在于解压缩,而是将解压缩的数据写回磁盘的效率低下.我的基准测试显示使用
InputStream is = zip.getInputStream(entry); // get the input stream
OutputStream os = new java.io.FileOutputStream(f);
byte[] buf = new byte[4096];
int r;
while ((r = is.read(buf)) != -1) {
os.write(buf, 0, r);
}
os.close();
is.close();
Run Code Online (Sandbox Code Playgroud)
相反,将方法的执行时间减少了5倍(对于6 MB的zip文件,从5秒减少到1秒).
可能的罪魁祸首是你的使用bis.available().除了不正确(可用返回读取调用之前的字节数将阻塞,直到流的末尾),这将绕过BufferedInputStream提供的缓冲,需要对复制到输出文件中的每个字节进行本机系统调用.
请注意,如果您像上面一样使用批量读取和写入方法,并且关闭资源的代码不是异常安全的(如果读取或写入因任何原因失败,is也os不会关闭),则无需包装在BufferedStream中).最后,如果你在类路径中有IOUtils,我建议使用经过良好测试IOUtils.copy而不是自己编辑.