【问题标题】:Is there a way to read a specific file from a ZipInputStream without having to iterate over the whole entry set?有没有办法从 ZipInputStream 读取特定文件而不必遍历整个条目集?
【发布时间】:2015-06-23 16:16:31
【问题描述】:

我想知道是否有一种方法可以直接从 ZipFile / ZipInputStream 读取特定文件,而无需遍历整个条目集。如果存档包含大量文件,我想这可能是相当大的开销。有没有更好的办法?

我知道这可以用TrueZip 来完成,而且我前段时间已经完成了,但我想知道现在 1.8 SDK 是否包含更合适的东西......?

【问题讨论】:

  • AFAIK 不。我倾向于迭代它并构建列表或地图
  • 不,没有。该文件位于 ZIP 文件中的某个位置,您必须迭代才能找到它。它并不像你想象的那么昂贵,只是一系列的寻找。

标签: java zipinputstream


【解决方案1】:

在 java 7 中,您可以处理 zip files as a Filesystem

虽然这确实提供了一些方便的访问方法,但它与遍历条目列表以查找单个文件相比不太可能执行任何不同的操作。

获取特定路径的输入流:

Path zipfile = Paths.get("/codeSamples/zipfs/zipfstest.zip");
FileSystem fs = FileSystems.newFileSystem(zipfile, null);
Path entry = fs.getPath("/my/entry.txt");
InputStream is = Files.newInputStream(entry);

完成后请务必close FileSystem 实例。

http://docs.oracle.com/javase/8/docs/api/java/nio/file/FileSystem.html#getPath-java.lang.String-java.lang.String...-

http://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#newInputStream-java.nio.file.Path-java.nio.file.OpenOption...-

【讨论】:

  • 我应该明白你可以简单地用FileInputStream 包装从FileSystem 获得的Path,然后继续阅读它吗? (一个例子会很棒)。
  • @carlspring 我添加了一个简单的例子。请注意,我链接到的 Zip 文件系统提供程序上的 oracle 文档包括一些简单的示例和指向源代码的链接以及更深入的示例。
  • 感谢这个例子,但它不能编译,因为FileSystem.newFileSystem 接受String,而不是Path。从我所见,路径似乎需要像uri:file:///path/to/foo.txt,但我似乎无法让它工作。上面的代码你试过了吗?
  • 我从 Oracle 文档中复制。我更新以反映可用的方法。你真的阅读过 Oracle 文档吗?第二句声明:The zip file system provider treats a zip or JAR file as a file system...
【解决方案2】:

ZipFile 具有执行此操作的 getEntry(String) 方法。但是,如果您的意思是代码从不遍历条目,那么不,您不能这样做。 zip 文件中的条目是无序的,因此您可以获得的最佳结果是 O(n) 迭代搜索。

Javadoc link

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 2019-09-14
    • 2011-03-07
    • 1970-01-01
    • 1970-01-01
    • 2015-06-13
    • 1970-01-01
    相关资源
    最近更新 更多