Reputation: 495
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
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