GoAlves
GoAlves

Reputation: 495

java: Zip Exception invalid codes length?

When I'm writing entries into a zip file like this:

ZipEntry ze = zin.getNextEntry();
while (ze != null) {
InputStream is = zf.getInputStream(ze);
zos.putNextEntry(ze);
int len;
while ((len = is.read(buffer)) >= 0) {
   zos.write(buffer, 0, len);
}

zos.closeEntry();
ze = zin.getNextEntry();

}

I get the following exception on the second while loop:

java.util.zip.ZipException: invalid code lengths set

at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:164)

at java.io.FilterInputStream.read(FilterInputStream.java:107)

Anybody knows why this exception is thrown and what does it mean?

P.S. I should mention that I'm running this on a listeners on JBoss 7.1.1 in order to zip vaious log files from different folders. There's a thread for each folder. Could the fact of using multiple threads lead to this problem?

Upvotes: 4

Views: 24856

Answers (1)

Holger
Holger

Reputation: 298143

You are setting the ZipEntry of the new zip file to the same instance you got from the original file. This implies that all values must match, but this fails if the compressed size of the written entry does not match the compressed size of the source file. And the tiniest bit of difference between the original compression code and the one you are using now will yield to different compressed sizes. To make it run you have to create a copy of the ZipEntry for the output and reset the compressed size on it.

By the way, you are using zin.getNextEntry() and zf.getInputStream(ze) in your code which implies that you are using a ZipFile and a ZipInputStream at the same time. If they refer to the same file, it’s a waste of resources, if they refer to different files, you can expect even more problems.

Decide for either ZipFile

ZipFile zf = …
ZipOutputStream zos = …
byte[] buffer = …

for(Enumeration<? extends ZipEntry> e=zf.entries(); e.hasMoreElements();) {
  ZipEntry ze = e.nextElement();
  InputStream is = zf.getInputStream(ze);
  ZipEntry zeOut=new ZipEntry(ze);
  zeOut.setCompressedSize(-1);
  zos.putNextEntry(zeOut);
  int len;
  while ((len = is.read(buffer)) >= 0) {
     zos.write(buffer, 0, len);
  }
  zos.closeEntry();
}
zos.close();
zf.close();

or ZipInputStream

ZipInputStream zin…
ZipOutputStream zos=…
byte[] buffer = …

ZipEntry ze = zin.getNextEntry();
while (ze != null) {
  ZipEntry zeOut=new ZipEntry(ze);
  zeOut.setCompressedSize(-1);
  zos.putNextEntry(zeOut);
  int len;
  while ((len = zin.read(buffer)) >= 0) {
     zos.write(buffer, 0, len);
  }
  zos.closeEntry();
  ze = zin.getNextEntry();
}
zos.close();
zin.close();

Upvotes: 4

Related Questions