2

I would like to know if there is a way to read a particular file directly from a ZipFile / ZipInputStream without having to iterate over the entire entry set. I imagine this could be quite an overhead, if the archive contains a large number of files. Is there a better way?

I know this can be done with TrueZip and I've done it a while ago, but I am wondering if the 1.8 SDK contains something more adequate nowadays...?

carlspring
  • 31,231
  • 29
  • 115
  • 197

2 Answers2

3

In java 7, you can treat zip files as a Filesystem.

While this does give some convenient access methods, it is not likely going to perform any different than iterating over the list of entries to find a single file.

To obtain a input stream for a specific path:

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);

Also be sure to close the FileSystem instance when you are done with it.

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...-

Brett Okken
  • 6,210
  • 1
  • 19
  • 25
  • Should I understand you can simply wrap the `Path` obtained from the `FileSystem` with a `FileInputStream` and just go ahead and read it? (An example would be great). – carlspring Apr 17 '15 at 03:48
  • @carlspring I have added a simple example. Note that the oracle doc on the Zip File System Provider that I linked to includes some simple examples and a link to source code with more in depth examples. – Brett Okken Apr 17 '15 at 11:46
  • Thanks, for the example, but it doesn't compile, as `FileSystem.newFileSystem` accepts a `String`, not a `Path`. From what I've seen, the path seems to need to be like `uri:file:///path/to/foo.txt`, but I can't seem to get it to work. Have you tried the code above? – carlspring Apr 17 '15 at 22:43
  • I copied from the Oracle doc. I updated to reflect the available method. Have you actually read the Oracle doc? The second sentence states: `The zip file system provider treats a zip or JAR file as a file system...` – Brett Okken Apr 18 '15 at 13:40
0

ZipFile has the getEntry(String) method for doing this. If you mean with the code never iterating through the entries, however, then no, you can not do it. The entries in a zip file are unordered so the best you can get is the O(n) iterative search.

Javadoc link

Andrew Vitkus
  • 827
  • 7
  • 9