tags:

views:

169

answers:

1

Hello All,

I have a zip file which can contain any number of zipfiles inside it (recursively also). I need to iterate over all of them.

Right now, i have a function which takes zipInputStream and zipFile as parameters. The problem is; if i get a zip inside another zip, i am calling this function recursively again. So i dont know how to create a zipFile object for zipfiles inside another zipfile. Can someone suggest a way to do it? Have you come across this before.

The snippet will look like this.

private void checkZIP(ZipInputStream zInpStream, ZipFile zf) {
  try {  
    ZipEntry zipEntry = zInpStream.getNextEntry();
    while (zipEntry != null) {
       String entryName = zipEntry.getName();

       if(entryName.endsWith(".zip"))
          checkZIP(new ZipInputStream(zf.getInputStream(zipEntry)),<NEW ZIPFILE OBJECT FOR THIS ENTRY>);


       //other files parsing apart from zip.

       zInpStream.closeEntry();
       zipEntry = zInpStream.getNextEntry();
    }
    zInpStream.close();
  } catch(Exception ioe) {
    //catching specific exceptions here. But did not want to put al
  } 
}

EDIT: I need that zip file object because. If i come across an XML file, i need to create a Document object. So if i pass the normal zipInputStream for parse() method in DocumentBuilder, it closes the stream and i am not able to use it again. So i used (ZipFile object).getInputStream(currentEntryForXML) inside DocumentBuilder parse().

+3  A: 

You can't create a ZipFile for the zip file inside archive. But why you need this argument in your method? If your only need a stream, just use your argument zInpStream as contstructor parameter, like

checkZIP(new ZipInputStream(zInpStream));

After call to zInpStream.getNextEntry() zInpStream is already positioned at the beginning of that entry and will read only that entry until getNextEntry() will be called.

Edit. Saw your edit. Seems, if you prevent stream closing, it will be sufficient for you. Just use slightly modified FilterInputStream, which delegates close() call to closeEntry() in zipInputStream, not a close.

public class ZipGuard extends java.io.FilterInputStream {
    public ZipGuard(ZipInputStream is) {
        super(is);
    }

    @Override
    public void close() throws IOException {
        ((ZipInputStream) in).closeEntry();
    }
}

And create this guard in checkZip:

checkZip(new ZipInputStream(new ZipGuard(zInpStream)));
maxkar
Please check my edit. I use the same stream for parsing the XML, if i get one inside the zip. And it closes the stream.
Aviator
It worked!! :) Thanks a lot!! :)
Aviator