I can go through ZipInputStream
, but before starting the iteration I want to get a specific file that I need during the iteration. How can I do that?
ZipInputStream zin = new ZipInputStream(myInputStream)
while ((entry = zin.getNextEntry()) != null)
{
println entry.getName()
}
If the myInputStream
you're working with comes from a real file on disk then you can simply use java.util.zip.ZipFile
instead, which is backed by a RandomAccessFile
and provides direct access to the zip entries by name. But if all you have is an InputStream
(e.g. if you're processing the stream directly on receipt from a network socket or similar) then you'll have to do your own buffering.
You could copy the stream to a temporary file, then open that file using ZipFile
, or if you know the maximum size of the data in advance (e.g. for an HTTP request that declares its Content-Length
up front) you could use a BufferedInputStream
to buffer it in memory until you've found the required entry.
BufferedInputStream bufIn = new BufferedInputStream(myInputStream);
bufIn.mark(contentLength);
ZipInputStream zipIn = new ZipInputStream(bufIn);
boolean foundSpecial = false;
while ((entry = zin.getNextEntry()) != null) {
if("special.txt".equals(entry.getName())) {
// do whatever you need with the special entry
foundSpecial = true;
break;
}
}
if(foundSpecial) {
// rewind
bufIn.reset();
zipIn = new ZipInputStream(bufIn);
// ....
}
(I haven't tested this code myself, you may find it's necessary to use something like the commons-io CloseShieldInputStream
in between the bufIn
and the first zipIn
, to allow the first zip stream to close without closing the underlying bufIn
before you've rewound it).