Java 使用 ByteArrayOutputStream 创建的 Zip 文件小于使用 FileOutputStream 创建的 Zip 文件
Java Zip File Created With ByteArrayOutputStream is smaller than with FileOutputStream
使用 ByteArrayOuputStream 输出的 Zip 文件小于使用 FileOutputStream 输出的 Zip 文件。
在 Java 中,我正在创建一个 Zip 文件。当我使用 FileOutputStream 时打开成功。
当将 FileOutputStream 切换为 ByteArrayOutputStream 时,我得到一个稍小的文件,大约 221 字节。此文件打不开,但与另一个文件内容相同,但少了 221 个字节。
在这两种情况下,我用来构建 Zip 文件的逻辑是相同的。因此,我将在不创建 zip 的情况下分享基本逻辑(如果您需要,请告诉我)。
ByteArrayOutputStream baos = new ByteArrayOutputStream();
zipOS = new ZipOutputStream(baos);
然后我创建 Zip 文件,然后...
zipOS.flush();
baos.flush();
baos.writeTo(new FileOutputStream("TEST_AS_BYTESTREAM_1.zip"));
zipOS.close();
baos.close();
我正在使用 baos.writeTo() 来绕过它以证明问题不是 HTTP 响应而是 ByteArrayOutputStream 元素。
使用时baos.writeTo(new FileOutputStream("TEST_AS_BYTESTREAM_1.zip"));
我得到一个较小的文件,无法以 Zip 格式打开。
此逻辑位于 java 控制器中,因此 link 单击网页将下载 zip 文件,而不会触及除用户以外的任何文件系统。
这是使用 FileOutputStream 的有效代码...
FileOutputStream baos = new FileOutputStream("TEST_AS_FILE.zip");
zipOS = new ZipOutputStream(baos);
除此之外,第二个代码片段不相关,因为我需要发送在网络服务器上创建的文件。但关键是,同样逻辑的Fileoutput流和ByteArrayOutputStream是有区别的。
下列说法错误的是:
baos.writeTo(new FileOutputStream("TEST_AS_BYTESTREAM_1.zip"));
writeTo(OutputStream out)
的 javadoc 没有说明关闭 OutputStream
的任何内容,这意味着它没有,所以最后的数据仍然坐在未关闭的缓冲中,未-脸红了FileOutputStream
.
正确的方法是:
try (OutputStream out = new FileOutputStream("TEST_AS_BYTESTREAM_1.zip")) {
baos.writeTo(out);
}
还有一个ByteArrayOutputStream
does not need to be closed or flushed. As the javadoc of close()
说:
Closing a ByteArrayOutputStream
has no effect.
不过,您需要致电 finish()
on an ZipOutputStream
才能完成内容。由于关闭 zip 流会自动为您完成,因此正确的做法是:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ZipOutputStream zipOS = new ZipOutputStream(baos)) {
// create the Zip file content here
}
try (OutputStream out = new FileOutputStream("TEST_AS_BYTESTREAM_1.zip")) {
baos.writeTo(out);
}
直接写入文件时:
try (ZipOutputStream zipOS = new ZipOutputStream(new FileOutputStream("TEST_AS_FILE.zip"))) {
// create the Zip file content here
}
考虑添加 BufferedOutputStream
以获得更好的性能。
最终答案如下。非常感谢之前给出的答案。
基本上我需要使用 ZipOuputStream 的 .finish() 方法。其他一切都保持不变。
压缩前创建代码与之前相同
ByteArrayOutputStream baos = new ByteArrayOutputStream();
zipOS = new ZipOutputStream(baos);
Post zip 创建...
zipOS.flush();
zipOS.finish();
baos.flush();
documentBody = baos.toByteArray();
zipOS.close();
baos.close();
那么我的 HTTP 响应是
HttpHeaders headers = new HttpHeaders();
headers.setContentType(new MediaType("application", "zip"));
headers.setContentLength(documentBody.length);
headers.add("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
ByteArrayResource resource = new ByteArrayResource(documentBody);
return ResponseEntity.ok()
.headers(headers)
.body(resource);
这样我就避免了创建一个很好的文件。
非常感谢您的帮助。
使用 ByteArrayOuputStream 输出的 Zip 文件小于使用 FileOutputStream 输出的 Zip 文件。
在 Java 中,我正在创建一个 Zip 文件。当我使用 FileOutputStream 时打开成功。
当将 FileOutputStream 切换为 ByteArrayOutputStream 时,我得到一个稍小的文件,大约 221 字节。此文件打不开,但与另一个文件内容相同,但少了 221 个字节。
在这两种情况下,我用来构建 Zip 文件的逻辑是相同的。因此,我将在不创建 zip 的情况下分享基本逻辑(如果您需要,请告诉我)。
ByteArrayOutputStream baos = new ByteArrayOutputStream();
zipOS = new ZipOutputStream(baos);
然后我创建 Zip 文件,然后...
zipOS.flush();
baos.flush();
baos.writeTo(new FileOutputStream("TEST_AS_BYTESTREAM_1.zip"));
zipOS.close();
baos.close();
我正在使用 baos.writeTo() 来绕过它以证明问题不是 HTTP 响应而是 ByteArrayOutputStream 元素。
使用时baos.writeTo(new FileOutputStream("TEST_AS_BYTESTREAM_1.zip"));
我得到一个较小的文件,无法以 Zip 格式打开。
此逻辑位于 java 控制器中,因此 link 单击网页将下载 zip 文件,而不会触及除用户以外的任何文件系统。
这是使用 FileOutputStream 的有效代码...
FileOutputStream baos = new FileOutputStream("TEST_AS_FILE.zip");
zipOS = new ZipOutputStream(baos);
除此之外,第二个代码片段不相关,因为我需要发送在网络服务器上创建的文件。但关键是,同样逻辑的Fileoutput流和ByteArrayOutputStream是有区别的。
下列说法错误的是:
baos.writeTo(new FileOutputStream("TEST_AS_BYTESTREAM_1.zip"));
writeTo(OutputStream out)
的 javadoc 没有说明关闭 OutputStream
的任何内容,这意味着它没有,所以最后的数据仍然坐在未关闭的缓冲中,未-脸红了FileOutputStream
.
正确的方法是:
try (OutputStream out = new FileOutputStream("TEST_AS_BYTESTREAM_1.zip")) {
baos.writeTo(out);
}
还有一个ByteArrayOutputStream
does not need to be closed or flushed. As the javadoc of close()
说:
Closing a
ByteArrayOutputStream
has no effect.
不过,您需要致电 finish()
on an ZipOutputStream
才能完成内容。由于关闭 zip 流会自动为您完成,因此正确的做法是:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ZipOutputStream zipOS = new ZipOutputStream(baos)) {
// create the Zip file content here
}
try (OutputStream out = new FileOutputStream("TEST_AS_BYTESTREAM_1.zip")) {
baos.writeTo(out);
}
直接写入文件时:
try (ZipOutputStream zipOS = new ZipOutputStream(new FileOutputStream("TEST_AS_FILE.zip"))) {
// create the Zip file content here
}
考虑添加 BufferedOutputStream
以获得更好的性能。
最终答案如下。非常感谢之前给出的答案。
基本上我需要使用 ZipOuputStream 的 .finish() 方法。其他一切都保持不变。
压缩前创建代码与之前相同
ByteArrayOutputStream baos = new ByteArrayOutputStream();
zipOS = new ZipOutputStream(baos);
Post zip 创建...
zipOS.flush();
zipOS.finish();
baos.flush();
documentBody = baos.toByteArray();
zipOS.close();
baos.close();
那么我的 HTTP 响应是
HttpHeaders headers = new HttpHeaders();
headers.setContentType(new MediaType("application", "zip"));
headers.setContentLength(documentBody.length);
headers.add("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
ByteArrayResource resource = new ByteArrayResource(documentBody);
return ResponseEntity.ok()
.headers(headers)
.body(resource);
这样我就避免了创建一个很好的文件。
非常感谢您的帮助。