Java的解压缩实用程序性能不佳

Ton*_*ony 8 java unzip

我注意到与使用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提供的缓冲,需要对复制到输出文件中的每个字节进行本机系统调用.

请注意,如果您像上面一样使用批量读取和写入方法,并且关闭资源的代码不是异常安全的(如果读取或写入因任何原因失败,isos不会关闭),则无需包装在BufferedStream中).最后,如果你在类路径中有IOUtils,我建议使用经过良好测试IOUtils.copy而不是自己编辑.


Jim*_*ugh 3

确保您在 Java 应用程序中向 unzip 方法提供 BufferedInputStream。如果您错误地使用了无缓冲输入流,那么您的 IO 性能肯定会很差。