通过 Chrome 浏览器从 ServletOutputStream 创建和传递的 zip 文件出现问题
Problems with zip file created and passed from ServletOutputStream via Chrome browser
我设置了一种方法,从我们的 S3 存储桶中输入多个数据文件,试图将它们压缩在一起,然后将它们传递给通过浏览器查询的用户。但是,我无法打开发回的文件。
我已经用 FileOutputStream 进行了测试,并且 zip 文件以正确的格式存储在那里,所以看起来拉、压缩和写入的过程正在运行。
我假设通过 ServletOutputStream 将其传回时存在问题,ServletOutputStream 是使用您在下面看到的 getResponse().getOutputStream()
提取的。然后我在上面调用了 write 方法,这个过程似乎对程序其他部分的 byte[] 格式的单个文件工作正常,只是这里没有。
另一块拼图,我输出的 zip 格式文件和通过 FileOutputStream 工作的文件与通过浏览器和 ServletOutputStream 传送的文件大小相同,所以我认为数据正在结束。相反,虽然我只是得到一个(错误 79 - 不合适的文件类型或格式。)
接受任何建议或帮助!!
File file;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(byteArrayOutputStream);
for (String fileName : fileList) {
key = fileName.replaceAll("=", "%3D");
file = s3Client.get(bucket, key, Paths.get("/tmp/" + fileName));
FileInputStream fis = new FileInputStream(file);
ZipEntry zipEntry = new ZipEntry(fileName);
zos.putNextEntry(zipEntry);
//Buffer used to read input stream
byte[] buffer = new byte[4096];
int length;
while ((length = fis.read(buffer)) != -1) {
//Read input stream to buffer and write this to zip output stream
zos.write(buffer, 0, length);
}
zos.closeEntry();
fis.close();
}
zos.flush();
getResponse().setContentType("application/zip");
getResponse().setContentLength(byteArrayOutputStream.size());
getResponse().setHeader("Content-Disposition", "attachment; filename=\"" + "test" + "." + "zip" + "\"");
getResponse().setHeader("Connection", "keep-alive");
getResponse().setHeader("Cache-Control", "private");
getResponse().setHeader("Pragma", "private");
getResponse().setDateHeader("Expires", System.currentTimeMillis() + 300000);
getResponse().getOutputStream().write(byteArrayOutputStream.toByteArray());
getResponse().getOutputStream().flush();
zos.close();
byteArrayOutputStream.close();
您没有正确关闭 ZipOutputStream
- 对 zos.close();
的调用必须发生在写入字节之前,而不是之后。
如果使用 try with resources 块和 Files.copy
:
,您可以获得更整洁的输出处理
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try(ZipOutputStream zos = new ZipOutputStream(byteArrayOutputStream)) {
for (String fileName : fileList) {
key = fileName.replaceAll("=", "%3D");
Path file = s3Client.get(bucket, key, Paths.get("/tmp/" + fileName)).toPath();
ZipEntry zipEntry = new ZipEntry(fileName);
zos.putNextEntry(zipEntry);
Files.copy(file, zos);
}
};
getResponse().setContentType("application/zip");
getResponse().setContentLength(byteArrayOutputStream.size());
getResponse().setHeader("Content-Disposition", "attachment; filename=\"" + "test" + "." + "zip" + "\"");
getResponse().setHeader("Connection", "keep-alive");
getResponse().setHeader("Cache-Control", "private");
getResponse().setHeader("Pragma", "private");
getResponse().setDateHeader("Expires", System.currentTimeMillis() + 300000);
getResponse().getOutputStream().write(byteArrayOutputStream.toByteArray());
getResponse().getOutputStream().flush();
我设置了一种方法,从我们的 S3 存储桶中输入多个数据文件,试图将它们压缩在一起,然后将它们传递给通过浏览器查询的用户。但是,我无法打开发回的文件。
我已经用 FileOutputStream 进行了测试,并且 zip 文件以正确的格式存储在那里,所以看起来拉、压缩和写入的过程正在运行。
我假设通过 ServletOutputStream 将其传回时存在问题,ServletOutputStream 是使用您在下面看到的 getResponse().getOutputStream()
提取的。然后我在上面调用了 write 方法,这个过程似乎对程序其他部分的 byte[] 格式的单个文件工作正常,只是这里没有。
另一块拼图,我输出的 zip 格式文件和通过 FileOutputStream 工作的文件与通过浏览器和 ServletOutputStream 传送的文件大小相同,所以我认为数据正在结束。相反,虽然我只是得到一个(错误 79 - 不合适的文件类型或格式。)
接受任何建议或帮助!!
File file;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(byteArrayOutputStream);
for (String fileName : fileList) {
key = fileName.replaceAll("=", "%3D");
file = s3Client.get(bucket, key, Paths.get("/tmp/" + fileName));
FileInputStream fis = new FileInputStream(file);
ZipEntry zipEntry = new ZipEntry(fileName);
zos.putNextEntry(zipEntry);
//Buffer used to read input stream
byte[] buffer = new byte[4096];
int length;
while ((length = fis.read(buffer)) != -1) {
//Read input stream to buffer and write this to zip output stream
zos.write(buffer, 0, length);
}
zos.closeEntry();
fis.close();
}
zos.flush();
getResponse().setContentType("application/zip");
getResponse().setContentLength(byteArrayOutputStream.size());
getResponse().setHeader("Content-Disposition", "attachment; filename=\"" + "test" + "." + "zip" + "\"");
getResponse().setHeader("Connection", "keep-alive");
getResponse().setHeader("Cache-Control", "private");
getResponse().setHeader("Pragma", "private");
getResponse().setDateHeader("Expires", System.currentTimeMillis() + 300000);
getResponse().getOutputStream().write(byteArrayOutputStream.toByteArray());
getResponse().getOutputStream().flush();
zos.close();
byteArrayOutputStream.close();
您没有正确关闭 ZipOutputStream
- 对 zos.close();
的调用必须发生在写入字节之前,而不是之后。
如果使用 try with resources 块和 Files.copy
:
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try(ZipOutputStream zos = new ZipOutputStream(byteArrayOutputStream)) {
for (String fileName : fileList) {
key = fileName.replaceAll("=", "%3D");
Path file = s3Client.get(bucket, key, Paths.get("/tmp/" + fileName)).toPath();
ZipEntry zipEntry = new ZipEntry(fileName);
zos.putNextEntry(zipEntry);
Files.copy(file, zos);
}
};
getResponse().setContentType("application/zip");
getResponse().setContentLength(byteArrayOutputStream.size());
getResponse().setHeader("Content-Disposition", "attachment; filename=\"" + "test" + "." + "zip" + "\"");
getResponse().setHeader("Connection", "keep-alive");
getResponse().setHeader("Cache-Control", "private");
getResponse().setHeader("Pragma", "private");
getResponse().setDateHeader("Expires", System.currentTimeMillis() + 300000);
getResponse().getOutputStream().write(byteArrayOutputStream.toByteArray());
getResponse().getOutputStream().flush();