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

时间:2011-03-30 08:56:44

标签: java unzip compression

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

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

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

请问??? ???

3 个答案:

答案 0 :(得分:15)

您使用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;
    }
}

答案 1 :(得分:10)

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

从zip文件META-INF/MANIFEST.MF中提取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());
}

答案 2 :(得分:6)

使用ZipFile而不是ZipInputStream

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

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

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