随机访问Zip文件而不将其写入磁盘

7 java zip

我有一个1-2GB的zip文件,500-1000k条目.我需要在几分之一秒内按名称获取文件,而不需要完全解压缩.如果文件存储在HDD上,这可以正常工作:

public class ZipMapper {
    private HashMap<String,ZipEntry> map;
    private ZipFile zf;

    public ZipMapper(File file) throws IOException {
        map = new HashMap<>();
        zf = new ZipFile(file);

        Enumeration<? extends ZipEntry> en = zf.entries();
        while(en.hasMoreElements()) {
            ZipEntry ze = en.nextElement();
            map.put(ze.getName(), ze);
        }
    }

    public Node getNode(String key) throws IOException {
        return Node.loadFromStream(zf.getInputStream(map.get(key)));
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果程序从Amazon S3下载zip文件并具有其InputStream(或字节数组),我该怎么办?虽然下载1GB需要大约1秒钟,但将其写入硬盘可能需要一些时间,而且由于我们没有硬盘垃圾收集器,因此处理多个文件会稍微困难一些.

ZipInputStream不允许随机访问条目.

通过字节数组在内存中创建虚拟文件会很好,但我找不到办法.

Puc*_*uce 2

您可以标记要在退出时删除的文件。

如果您想采用内存中方法:请查看新的 NIO.2 文件 API。Oracle 为 zip/jar 提供文件系统提供程序,而 AFAIK ShrinkWrap提供内存中文件系统。您可以尝试将两者结合起来。

我编写了一些实用方法来使用 NIO.2 文件 API(该库是开源的)将目录和文件复制到 Zip 文件或从 Zip 文件复制目录和文件:

行家:

<dependency>  
    <groupId>org.softsmithy.lib</groupId>  
    <artifactId>softsmithy-lib-core</artifactId>  
    <version>0.3</version>  
</dependency>  
Run Code Online (Sandbox Code Playgroud)

教程:

http://softsmithy.sourceforge.net/lib/current/docs/tutorial/nio-file/index.html

API:CopyFileVisitor.copy

尤其是PathUtils.resolve有助于解析跨文件系统的路径。