Java 使用ZipOutStream的zip文件已损坏

Java 使用ZipOutStream的zip文件已损坏,java,zipoutputstream,Java,Zipoutputstream,我正在尝试创建一个zip文件,以便能够通过http发送多个文件 我的问题是生成的Zip文件在发送之前和之后都“损坏”。问题是我无法找到我做错了什么,因为我在控制台中没有收到任何错误 有人有想法吗?我生成的zip文件已损坏 这是我的代码: OutputStream responseBody = t.getResponseBody(); ByteArrayOutputStream baos = new ByteArrayOutputStream();

我正在尝试创建一个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();


谢谢你的帮助

您需要从循环内部删除
zos.finish()
,因为它会终止ZIP条目,因为它是由流末尾的
zos.close()
处理的

对于非常大的流,您最好绕过
ByteArrayOutputStream
内存缓冲区,直接将ZIP发送到响应库

如果仍然存在问题,请检查是否设置了输出的内容类型。通过将字节[]临时写入文件以检查发送的ZIP格式,调试可能会更容易:

Files.write(Path.of("temp.zip"), baos.toByteArray());
下面的大纲显示了通过http发送一个简单的ZIP(从servlet,将前两行调整为适当的“t”调用)。如果返回到在循环中添加自己的文档对象,这可能有助于检查代码的哪个步骤导致损坏:

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

即使在这些修改之后,zip仍然损坏@DuncG如果zos.finish()在循环中,那么zip将只包含第一个条目。@MichelMelhem DuncG完全正确,您需要删除每个ByteArrayOutputStream。您正在扼杀程序的性能!只需将响应的输出体包装在Zipoutput流中并直接写入即可。如果您的目标是发送多个文件而不是专门的zip,则可以使用多部分/表单数据,可能还需要进行部分压缩。