问题描述
我正在尝试创建一个zip文件,以便能够通过http发送多个文件。
我的问题是,发送该文件之前和之后,生成的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直接发送到responseBody。
如果仍然有问题,请检查输出的内容类型是否已设置。通过将byte []临时写入文件以检查发送的ZIP格式,可能更容易调试:
Files.write(Path.of("temp.zip"),baos.toByteArray());
以下概述显示了通过http发送简单的ZIP(从servlet,将前2行调整为对“ 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());
}
}