我注意到,与使用 WinZip 等本机工具相比,Java 中的解压缩工具非常慢。
有没有更高效的 Java 第三方库?
开源是首选。
Edit
以下是使用 Java 内置解决方案与 7zip 的速度比较。
我在原来的解决方案中添加了缓冲输入/输出流(谢谢吉姆,这确实产生了很大的影响)。
压缩文件大小: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();
}
}
问题不在于解压缩,而在于将解压缩的数据写回磁盘的低效方式。我的基准测试表明使用
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();
相反,该方法的执行时间减少了 5 倍(6 MB zip 文件从 5 秒减少到 1 秒)。
可能的罪魁祸首是你使用bis.available()
。除了不正确(available 返回字节数,直到对 read 的调用会阻塞,而不是直到流结束),这绕过了 BufferedInputStream 提供的缓冲,需要对复制到输出文件中的每个字节进行本机系统调用。
请注意,如果您像上面那样使用批量读取和写入方法,则不需要包装在 BufferedStream 中,并且关闭资源的代码不是异常安全的(如果读取或写入因任何原因失败,也不是异常安全的)。is
nor os
将被关闭)。最后,如果类路径中有 IOUtils,我建议使用它们经过充分测试的IOUtils.copy http://commons.apache.org/io/api-1.4/org/apache/commons/io/IOUtils.html#copy%28java.io.InputStream,%20java.io.OutputStream%29而不是自己滚动。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)