损坏的 zip 文件,使用 ZipOutputStream

huangapple go评论73阅读模式
英文:

Corrupted zip file using ZipOutputStream

问题

我试图创建一个ZIP文件,以便能够通过HTTP发送多个文件。

我的问题是生成的ZIP文件在发送之前和之后都是“损坏”的。问题是,我无法找到我做错了什么,因为控制台内没有错误消息。

那么,有人知道为什么我的生成的ZIP文件会损坏吗?

这是我的代码:

  OutputStream responseBody = t.getResponseBody();
  ByteArrayOutputStream baos = new ByteArrayOutputStream();
  ZipOutputStream zos = new ZipOutputStream(baos);

  int counter = 1;
  for (PDDocument doc : documents)
  {
    ZipEntry zipEntry = new ZipEntry("document" + counter);
    zos.putNextEntry(zipEntry);
    ByteArrayOutputStream docOs = new ByteArrayOutputStream();
    doc.save(docOs);
    docOs.close();
    zos.write(docOs.toByteArray());
    zos.closeEntry();
    zos.finish();
    zos.flush();

    counter++;
  }
  zos.close();
  baos.close();

  responseBody.write(baos.toByteArray());
  responseBody.flush();

感谢您的帮助!

英文:

I'm trying to create a zip file to be able to send multiple files over http.

My issue is that the Zip file that is generated is "corrupted" before and after the file has been send. The issue is i'm not able to find what i did wrong as i'm getting no errors inside the console.

So does someone has an idea file my generated zip file is corrupted ?

This is my code :

  OutputStream responseBody = t.getResponseBody();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ZipOutputStream zos = new ZipOutputStream(baos);


            int counter = 1;
            for (PDDocument doc : documents)
            {
                ZipEntry zipEntry = new ZipEntry("document" + counter);
                zos.putNextEntry(zipEntry);
                ByteArrayOutputStream docOs = new ByteArrayOutputStream();
                doc.save(docOs);
                docOs.close();
                zos.write(docOs.toByteArray());
                zos.closeEntry();
                zos.finish();
                zos.flush();

                counter++;
            }
            zos.close();
            baos.close();


            responseBody.write(baos.toByteArray());
            responseBody.flush();

Thank you for your help !

答案1

得分: 3

你需要从循环内部移除 zos.finish(),因为它会终止ZIP条目,而这在流的末尾由 zos.close() 处理。

对于非常大的流,最好直接将ZIP发送到 responseBody,跳过 ByteArrayOutputStream 内存缓冲区。

如果仍然遇到问题,请检查输出的内容类型是否已设置。通过将字节数组暂时写入文件以检查发送的ZIP格式,可能会更容易进行调试:

Files.write(Path.of("temp.zip"), baos.toByteArray());

下面的概述展示了通过HTTP发送简单的ZIP(从Servlet发送,根据需要调整前两行以适应“t”的适当调用)。如果你逐步添加自己的文档对象到循环内部,这可能会帮助你检查代码的哪个步骤导致损坏:

// 必须设置响应内容类型:
// resp.setContentType("application/zip");
OutputStream out = resp.getOutputStream(); // 或 t.getResponseBody();
try (ZipOutputStream zos = new ZipOutputStream(out)) {
    while (counter-- > 0) {
        ZipEntry zipEntry = new ZipEntry("document" + counter + ".txt");
        zos.putNextEntry(zipEntry);
        zos.write(("This is ZipEntry: " + zipEntry.getName() + "\r\n").getBytes());
    }
}

注意:以上内容为您提供的代码的翻译部分。如有任何疑问,请随时提问。

英文:

You need to remove zos.finish() from inside the loop as it terminates the ZIP entries, as it is handled by zos.close() at end of the stream.

With very large streams you will be better off sending ZIP directly to responseBody bypassing ByteArrayOutputStream memory buffer.

If you are still having problems check the content type of the output is set. It might be easier to debug by temporarily writing the byte[] to file to check the ZIP format you are sending with:

Files.write(Path.of("temp.zip"), baos.toByteArray());

This outline below shows sending a simple ZIP over http (from a servlet, adjust the first 2 lines to appropriate calls for "t"). This may help you check which step of your code causes the corruption if you work back to adding your own document objects inside the loop:

// MUST set response content type:
// resp.setContentType("application/zip");
OutputStream out = resp.getOutputStream(); // or t.getResponseBody();
try(ZipOutputStream zos = new ZipOutputStream(out))
{
    while (counter-- > 0)
    {
        ZipEntry zipEntry = new ZipEntry("document" + counter+".txt");
        zos.putNextEntry(zipEntry);
        zos.write(("This is ZipEntry: "+zipEntry.getName()+"\r\n").getBytes());
    }
}

huangapple
  • 本文由 发表于 2020年8月24日 23:06:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/63563677.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定