4

当我将条目写入这样的 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)

任何人都知道为什么会抛出这个异常,这是什么意思?

PS 我应该提到我在 JBoss 7.1.1 上的侦听器上运行它,以便从不同的文件夹压缩各种日志文件。每个文件夹都有一个线程。使用多个线程的事实会导致这个问题吗?

4

1 回答 1

4

您正在将ZipEntry新 zip 文件的 zip 文件设置为从原始文件中获得的相同实例。这意味着所有值都必须匹配,但如果写入条目的压缩大小与源文件的压缩大小不匹配,则会失败。原始压缩代码与您现在使用的压缩代码之间的最微小差异将产生不同的压缩大小。要使其运行,您必须为ZipEntry输出创建一个副本并在其上重置压缩大小。

顺便说一句,您在代码中使用zin.getNextEntry()andzf.getInputStream(ze)意味着您同时使用 aZipFile和 a 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();
于 2013-10-28T11:35:56.050 回答