If the myInputStream you are working with comes from a real file on disk, you can simply use java.util.zip.ZipFile instead, which is supported by RandomAccessFile and provides direct access to zip records by name. But if all you have is an InputStream (for example, if you process the stream directly when receiving from a network socket or similar), you will need to do your own buffering.
You can copy the stream to a temporary file, then open this file with a ZipFile or, if you ZipFile know the maximum data size (for example, for an HTTP request declaring its Content-Length in front), you can use BufferedInputStream to buffer it in memory until until you find the record you want.
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 have not tested this code myself, you can find something like commons-io CloseShieldInputStream between bufIn and the first zipIn to allow closing the first zip stream without closing the underlying bufIn before rewinding it).
source share