从包含大量文件的zip文件中提取1个文件的最快方法是什么?

lam*_*988 12 java compression unzip

我试过java.util.zip包,它太慢了.

然后我找到了LZMA SDK7z jbinding,但他们也缺少一些东西.LZMA SDK没有提供一种如何使用的文档/教程,这非常令人沮丧.没有javadoc.

虽然7z jbinding不提供仅提取1个文件的简单方法,但它只提供了提取zip文件的所有内容的方法.而且,它没有提供指定放置解压缩文件的位置的方法.

请问???

Whi*_*g34 16

您的代码java.util.zip看起来像什么,以及您处理的zip文件有多大?

我能够在大约一秒钟内从一个200MB的zip文件中提取一个4MB的条目,其中1,800个条目:

OutputStream out = new FileOutputStream("your.file");
FileInputStream fin = new FileInputStream("your.zip");
BufferedInputStream bin = new BufferedInputStream(fin);
ZipInputStream zin = new ZipInputStream(bin);
ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
    if (ze.getName().equals("your.file")) {
        byte[] buffer = new byte[8192];
        int len;
        while ((len = zin.read(buffer)) != -1) {
            out.write(buffer, 0, len);
        }
        out.close();
        break;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果在FileInputStream和ZipInputStream之间有一个BufferedInputStream,你的代码会更快. (5认同)
  • 我假设你说的是每秒20个请求需要一个zip文件的单个文件.为什么不提前完全解压缩这些并直接从文件系统中提供它们? (2认同)
  • 另外,你不应该在最后做一个zin.close()吗? (2认同)

fla*_*nze 12

我没有对速度进行基准测试,但是对于java 7或更高版本,我提取文件如下.
我想它比ZipFile API 更快:

META-INF/MANIFEST.MF从zip文件中提取的简短示例test.zip:

// file to extract from zip file
String file = "MANIFEST.MF";
// location to extract the file to
File outputLocation = new File("D:/temp/", file);
// path to the zip file
Path zipFile = Paths.get("D:/temp/test.zip");

// load zip file as filesystem
try (FileSystem fileSystem = FileSystems.newFileSystem(zipFile, null)) {
    // copy file from zip file to output location
    Path source = fileSystem.getPath("META-INF/" + file);
    Files.copy(source, outputLocation.toPath());
}
Run Code Online (Sandbox Code Playgroud)


kdg*_*ory 6

使用ZipFile而不是ZipInputStream.

虽然文档没有说明这一点(它在文档中JarFile),但它应该使用随机访问文件操作来读取文件.由于ZIP文件包含已知位置的目录,这意味着在查找特定文件时必须少用IO.

一些警告:据我所知,Sun实现使用内存映射文件.这意味着您的虚拟地址空间必须足够大,以容纳文件以及JVM中的其他所有内容.这可能是32位服务器的问题.另一方面,它可能足够聪明,可以避免在32位上进行内存映射,或者只对目录进行内存映射; 我没试过.

此外,如果您使用多个文件,请务必使用try/ finally来确保文件在使用后关闭.