7

我有一个 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)));
    }
}

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

ZipInputStream 不允许随机访问条目。

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

4

5 回答 5

2

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

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

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

马文:

<dependency>  
    <groupId>org.softsmithy.lib</groupId>  
    <artifactId>softsmithy-lib-core</artifactId>  
    <version>0.3</version>  
</dependency>  

教程:

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

API:CopyFileVisitor.copy

特别是PathUtils.resolve有助于解决跨文件系统的路径。

于 2013-02-27T13:28:10.713 回答
1

您可以使用 SecureBlackbox 库,它允许对任何可搜索的流进行 ZIP 操作。

于 2013-02-27T13:31:26.763 回答
0

Blackbox 库只有 Extract(String name, String outputPath) 方法。似乎它确实可以随机访问可搜索 zip 流中的任何文件,但它不能将结果写入字节数组或返回流。

我找不到 ShrinkWrap 的文档。我找不到 FileSystem/FileSystemProvider 等的任何合适的实现。

然而,事实证明,我正在运行的 Amazon EC2 实例(大)以某种方式在大约 1 秒内将 1gb 文件写入磁盘。所以我只是将文件写入磁盘并使用 ZipFile。

如果 HDD 会很慢,我认为 RAM 磁盘将是最简单的解决方案。

于 2013-02-27T22:28:17.390 回答
0


我认为您应该考虑使用您的操作系统来创建“内存中”文件系统(即 RAM 驱动器)。
另外,看看FileSystem的 API。

于 2013-02-27T13:29:51.933 回答
0

一种完全不同的方法:如果服务器在磁盘上有文件(并且可能已经缓存在 RAM 中):让它直接给你文件。换句话说,提交您需要的文件,然后小心提取并在服务器上交付这些文件。

于 2013-02-27T14:36:09.180 回答