java - 处理 zip 中约 450.000 个文件

标签 java performance file-io zip out-of-memory

我的问题很简单。 Java 可以处理包含大约 450,000 个文件的 .zip 文件吗?我编写的代码不会加载所有文件,只会在 zip 中搜索一个特定文件,并逐行读取。文件大小约为500kb。

这会起作用还是会出现 OutOfMemory 异常?

哦,抱歉,未压缩时大约有 0.5MB。压缩后的整个文件大约 250mb。

好的,文件的名称是该 zip 文件中的 ID + 日期(唯一)。如果我必须检查日志,我会调用 Java 并提供 ID + 日期,Java 只会读取该文件,而不会读取更多文件。

编辑:它有效,它非常有效。一个 zip 中大约有 400.000 个文件,如果您有足够的内存来压缩文件,则不会出现任何问题。

Edit2:它在 Linux 文件系统上运行没有问题,在 NTFS 上有时会崩溃。 NTFS 对 1 Zip 中的 musch 文件存在问题。

最佳答案

使用 Java 7 中的 zip 文件系统,您实际上可以非常轻松地访问一个单独的文件在其上打开一个 BufferedReader

首先您必须创建文件系统:

public static FileSystem getZipFileSystem(final String zipPath)
{
    final Path path = Paths.get(zipPath).toAbsolutePath();
    final Map<String, Object> env = new HashMap<>();
    final URI uri = URI.create("jar:file:" + path.toString());
    return FileSystems.newFileSystem(uri, env, null);
}

完成此操作后,您可以从 zip 本身的条目创建一个 BufferedReader:

try (
    final FileSystem fs = getZipFileSystem("/path/to/the.zip");
    final BufferedReader reader = Files.newBufferedReader(fs.getPath("path/to/entry"),
        StandardCharsets.UTF_8);
) {
    // operate on the reader
}

您还可以使用 Files.readAllLines() 一次读取条目中的所有行。

如果您希望将 zip 条目复制到文件系统上的文件中,您也可以这样做:

Files.copy(zipfs.getPath("path/to/entry"), Paths.get("file/on/local/fs"));

或者您可以直接将结果复制到 OutputStream,或者直接从 OutputStream 创建条目...

甚至使用 Files.walkFileTree() 遍历整个 zip。

或者使用Files.newDirectoryStream()获取zip中“目录”中的所有条目。请注意,正如其名称所示,这是一个;与File.listFiles()(它只适用于磁盘上的文件)不同,这会返回一个遍历条目的迭代器。

或者...或者...或者...

请注意,FileSystem 需要是 .close()d。

关于java - 处理 zip 中约 450.000 个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22501507/

相关文章:

java - 为什么在以下代码中执行 (referenceTos[0] != null) 检查?

sql-server - 提高 SQL Server 数据库性能

batch-file - 批量将 100 个文件夹中的所有文件向上移动一个文件夹

c++ - 逐字符读取文本文件

java - 如何禁止 JTextField 中的特殊字符

java - Weld/CDI 的最佳调试技巧是什么?

java - autoComplete completeMethod 在对话框中不起作用

database - 包含( float ,整数)元组的 100 万个向量的高效比较

algorithm - 在 Haskell 中具有良好性能的简单循环

java - Libgdx 写入文件不起作用?