当我将条目写入这样的zip文件时:
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();
}
我在第二个while循环中遇到以下异常:
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)
任何人都知道为什么会抛出这个异常,它是什么意思?
P.S。我应该提一下,我正在JBoss 7.1.1上的监听器上运行它,以便从不同的文件夹中压缩vaious日志文件。每个文件夹都有一个帖子。使用多个线程的事实会导致这个问题吗?
答案 0 :(得分:3)
您正在将新zip文件的ZipEntry
设置为您从原始文件获得的同一实例。这意味着所有值必须匹配,但如果写入条目的压缩大小与源文件的压缩大小不匹配,则会失败。原始压缩代码与您现在使用的压缩代码之间的微小区别将产生不同的压缩大小。要使其运行,您必须为输出创建ZipEntry
的副本,并在其上重置压缩大小。
顺便说一句,您在代码中使用了zin.getNextEntry()
和zf.getInputStream(ze)
,这意味着您同时使用ZipFile
和ZipInputStream
。如果他们引用同一个文件,那就浪费了资源,如果他们引用不同的文件,你可能会遇到更多问题。
决定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();
或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();