views:

1106

answers:

4

Hello,

I am trying to write a Java class to extract a large zip file containing ~74000 XML files. I get the following exception when attempting to unzip it utilizing the java zip library:

java.util.zip.ZipException: too many entries in ZIP file

Unfortunately due to requirements of the project I can not get the zip broken down before it gets to me, and the unzipping process has to be automated (no manual steps). Is there any way to get around this limitation utilizing java.util.zip or with some 3rd party Java zip library?

Thanks.

+5  A: 

Using ZipInputStream instead of ZipFile should probably do it.

Tom Hawtin - tackline
Awesome, that worked thanks!
Andrew
A: 

The Zip standard supports a max of 65536 entries in a file. Unless the Java library supports ZIP64 extensions, it won't work properly if you are trying to read or write an archive with 74,000 entries.

Cheeso
A: 

Using apache IOUtils:

FileInputStream fin = new FileInputStream(zip);
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze = null;

while ((ze = zin.getNextEntry()) != null) {
    FileOutputStream fout = new FileOutputStream(new File(
        outputDirectory, ze.getName()));

    IOUtils.copy(zin, fout);

    IOUtils.closeQuietly(fout);
    zin.closeEntry();
}

IOUtils.closeQuietly(zin);
Andrew
A: 

I reworked the method to deal with directory structures more convenient and to zip a whole bunch of targets at once. Plain files will be added to the root of the zip file, if you pass a directory, the underlying structure will be preserved.

def zip (String zipFile, String [] filesToZip){ 
    def result = new ZipOutputStream(new FileOutputStream(zipFile))
    result.withStream { zipOutStream ->
     filesToZip.each {fileToZip ->
      ftz = new File(fileToZip)
      if(ftz.isDirectory()){
       pathlength = new File(ftz.absolutePath).parentFile.absolutePath.size()
       ftz.eachFileRecurse {f ->    
        if(!f.isDirectory()) writeZipEntry(f, zipOutStream, f.absolutePath[pathlength..-1]) 
       }
      }    
      else writeZipEntry(ftz, zipOutStream, '')
     }
    }
}

def writeZipEntry(File plainFile, ZipOutputStream zipOutStream, String path) {
    zipOutStream.putNextEntry(new ZipEntry(path+plainFile.name))
    new FileInputStream(plainFile).withStream { inStream ->
     def buffer = new byte[1024]
     def count
     while((count = inStream.read(buffer, 0, 1024)) != -1) 
      zipOutStream.write(buffer)     
    }
    zipOutStream.closeEntry()
}
t0rb3n