java:邮​​编异常无效代码长度?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19631409/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 18:57:49  来源:igfitidea点击:

java: Zip Exception invalid codes length?

javajboss7.xzipfile

提问by GoAlves

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

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

}

I get the following exception on the second while loop:

我在第二个 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)

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?

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

采纳答案by Holger

You are setting the ZipEntryof 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 ZipEntryfor the output and reset the compressed size on it.

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

By the way, you are using zin.getNextEntry()and zf.getInputStream(ze)in your code which implies that you are using a ZipFileand a ZipInputStreamat 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.

顺便说一句,您在代码中使用zin.getNextEntry()zf.getInputStream(ze)这意味着您同时使用 aZipFile和 a ZipInputStream。如果它们引用同一个文件,那就是浪费资源,如果它们引用不同的文件,则可能会出现更多问题。

Decide for either ZipFile

决定两者之一 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

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();