OutputStream的内存使用情况,用于文件下载

时间:2013-07-04 07:13:43

标签: java web-applications download outputstream

所以我不确定究竟是什么情况发生在内心深处。

假设我们在Web应用程序和用户请求中下载动态生成的文件,该文件的大小可能是几MB,甚至可能是100 MB或更多。该应用程序执行此操作

String disposition = "attachment; fileName="myFile.txt";
response.setHeader("Content-Disposition", disposition);
ServletOutputStream output = response.getOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(output);
service.exportFile(ids, writer, properties);

我是对的,整个文件永远不会完全在内存中吗?例如。生成的任何数据都会发送给用户,然后在服务器上丢弃(假设一切顺利,没有数据包丢失)?

我问这个是因为我需要更改生成文件的库(第三方),而新版本不需要使用标准的Java IO,因为它只是一个API而实际的库是在C中。无论如何获取文档说要调用的缓冲区数据

String data = buffer.toString();

(文件是ASCII)

我的假设是正确的,特别是当多个用户同时下载大文件时,内存消耗会受到影响吗?

2 个答案:

答案 0 :(得分:1)

是的,您首先将代码段数据直接流式传输到客户端,假设service.exportFile(ids, writer, properties)本身的实现从未将生成的数据保存在内存中,但实际上将其直接传输到写入器。

使用String data = buffer.toString();,您最终将整个数据放在堆空间中,最迟在调用buffer.toString()时,可能会更早,具体取决于具体实现。

总之,在我看来,你有两点意识到:   - 永远不要将数据分配给您的代码中的变量,而是直接将其写入输出流   - 确保implmentation也永远不会将整个数据保存在生成​​它的内存中

答案 1 :(得分:0)

第三方lib提供了第二种解决方案,即写入文件。但是,这需要额外的麻烦来创建唯一的文件名,然后读取它们并在之后删除它们。但无论如何我实施了它。

service.exportFile(ids, writer, properties)

ids是要导出的记录的数据库标识符的集合,因此ids.size()粗略估计了生成的文件大小。因此,只要它很小,我就使用缓冲区版本,如果它很大,则使用缓冲区版本。