gpt4 book ai didi

http - Servlet : response. setContentLength() 下载速度变慢

转载 作者:可可西里 更新时间:2023-11-01 15:07:27 34 4
gpt4 key购买 nike

private void downloadAllRelease(HttpServletRequest request,
HttpServletResponse response) {
LoginToken tok=getToken(request, response);
int size = 0;
try {
ArrayList<Release> releases = manager.getReleases(tok.getUsername);
ZipOutputStream out = new ZipOutputStream(response.getOutputStream());
for (int i=0; i<releases.size(); i++) {
size += releases.get(i).getFile().length;
out.putNextEntry(new ZipEntry(releases.get(i).getFilename()));
out.write(releases.get(i).getFile());
out.closeEntry();
}
response.setContentLength(size);
response.setContentType("application/force-download");
response.setHeader("Content-Disposition","attachment;filename=release.zip");
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}

response.setContentLength() 确实减慢了下载速度。
如果我不使用它或将它放在 out.close() 之后,一切仍然正常,但下载速度要快得多。
谁能解释一下为什么以及是否有必要使用 response.setContentLength()

最佳答案

也许是因为您指定的大小比实际发送到响应的大小大,并且网络浏览器基本上感到困惑并正在等待更多数据?您知道,ZIP 压缩文件并减小最终大小。

如果您不能事先有效地计算它,就不要指定响应的内容长度。 servlet 容器将 automaticallychunked encoding 发送反正。的确,这会产生更多的开销,并使网络浏览器的下载进度未知,但这并不需要您先在服务器内存中缓冲整个响应,以便您可以获得正确的最终响应内容长度。

如果您真的想要计算最终的响应内容长度,您需要将其全部写入ByteArrayOutputStream,然后获取byte[ ] 通过其 toByteArray() 方法。真正的响应内容长度就是byte[]的长度。

ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream out = new ZipOutputStream(baos);
// ...

response.setContentLength(baos.size());
response.getOutputStream().write(bytes);

这只是更多的内存占用,因为所有内容都将首先存储在服务器的内存中。如果多个用户同时执行此操作并且 zip 输出相对较大,那么您的服务器可能迟早会面临内存不足的风险。作为另一种选择,您可以使用 FileOutputStream 将其写入由 File#createTempFile() 创建的临时文件,以便您可以通过 File# 获取其大小length() 并使用 FileInputStream 以通常的方式将其直接流式传输到响应的 OutputStream 中。这只会更慢,因为您基本上要传输大约两次字节。

关于http - Servlet : response. setContentLength() 下载速度变慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8797035/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com