【问题标题】:Java.util.zip.ZipException: invalid entry size (expected 18401 but got 0 bytes) when using putNextEntry() in ZipOutputStream?Java.util.zip.ZipException:在 ZipOutputStream 中使用 putNextEntry() 时条目大小无效(预期为 18401 但得到 0 个字节)?
【发布时间】:2021-08-11 03:43:43
【问题描述】:

我将 5 个文件的 zip 文件转换为字节数组。我想从那个字节数组在我的磁盘上输出一个 zip 文件。我的过程是首先将 byte[] 读入 ByteArrayInputStream,然后读入 ZipInputStream。

InputStream plainTextStream = new ByteArrayInputStream(plainText);
ZipInputStream zipInStream = new ZipInputStream(plainTextStream);

我希望将其输出到磁盘上的 zip 文件中,因此我认为我需要一个文件和一个 ZipOutPutStream 来传递该 zip 文件。

ZipOutputStream zipOutStream = new ZipOutputStream(new FileOutputStream(file));

通过一个 zip 条目,我使用缓冲区遍历 ZipInPutStream 写入每个条目的 FileOutputStream。在每个主循环结束时,我将一个条目放入 ZipOutPutStream。

    ZipEntry entry = null;
    while((entry = zipInStream.getNextEntry()) != null){
        FileOutputStream fileOutStream = new FileOutputStream(entry.getName());
        byte[] byteBuff = new byte[1024];
        int bytesRead = 0;
        while ((bytesRead = zipInStream.read(byteBuff)) != -1)
        {
            fileOutStream.write(byteBuff, 0, bytesRead);
        }
        fileOutStream.close();
        zipOutStream.putNextEntry(entry);
        zipInStream.closeEntry();
    }

我添加了 zip 中的第一个文件(有 5 个文件),但是在尝试添加第二个文件时,我收到一个错误

zipOutStream.putNextEntry(entry)

java.util.zip.ZipException: invalid entry size (expected 18401 but got 0 bytes)

通过调试,我无法弄清楚哪里出了问题。我认为在放入第一个 outputstream(entry.getName()) 时它可能与缓冲区有关? bytesRead while 循环可能是个问题。 这一切都假设逻辑是有道理的。我希望我可以解决这个错误。

【问题讨论】:

  • 除非您正在编辑文件,而您不在显示的代码中,否则将输入流解码和重新编码为 ZIP 完全是浪费时间。只需将原始输入流复制到文件输出流即可。您的复制循环没问题,只是目前您正在写入错误的流。此外,您假设输入中没有目录条目。

标签: java inputstream outputstream zipoutputstream zipinputstream


【解决方案1】:

您永远不会将压缩文件的内容写入 zip 输出流。

您不需要将输出写入文件流,只需将其直接写入 zip 输出流即可。

您应该使用 try-with-resources。

try (ZipInputStream zipInStream = new ZipInputStream(new ByteArrayInputStream(plainText));
     ZipOutputStream zipOutStream = new ZipOutputStream(new FileOutputStream(file));
) {
    byte[] byteBuff = new byte[1024];
    for (ZipEntry entry; (entry = zipInStream.getNextEntry()) != null; ) {
        zipOutStream.putNextEntry(entry);
        for (int bytesRead; (bytesRead = zipInStream.read(byteBuff)) != -1; ) {
            zipOutStream.write(byteBuff, 0, bytesRead);
        }
    }
}

无需拨打closeEntry()

【讨论】:

  • 我很感激。为什么不需要 closeEntry() ?我认为每当将条目放入 zipOutStream 时都需要它。 putNextEntry(entry) 是否消除了需要?此外,生成的 zip 具有相同的文件,但它们的大小不同,大约有 kb。这正常吗?
  • @AlMahiyan 1) 阅读putNextEntry 的文档 --- 2) 他们可能使用了不同的压缩方法或级别。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-16
  • 2022-07-05
  • 2020-11-07
  • 2020-02-27
  • 1970-01-01
相关资源
最近更新 更多