所以我不确定究竟是什么情况发生在内心深处。
假设我们在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)
我的假设是正确的,特别是当多个用户同时下载大文件时,内存消耗会受到影响吗?
答案 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()
粗略估计了生成的文件大小。因此,只要它很小,我就使用缓冲区版本,如果它很大,则使用缓冲区版本。