0

所以我不太确定内心深处到底发生了什么。

假设我们在一个 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);

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

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

String data = buffer.toString();

(文件是ASCII)

那么我的假设是否正确,即内存消耗会受到影响,尤其是当多个用户同时下载大文件时?

4

2 回答 2

1

是的,您的第一个代码片段数据直接流式传输到客户端,假设其实现service.exportFile(ids, writer, properties)本身永远不会将生成的数据保存在内存中,而是真正将其直接流式传输到编写器。

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

总之,在我看来,您必须注意两件事:-永远不要将数据分配给您的 codem 中的变量,而是直接将其写入输出流-确保实现也永远不会在生成它时将整个数据保存在内存中

于 2013-07-04T08:03:17.190 回答
0

第 3 方库提供了第二种解决方案,即写入文件。但是,这需要额外的麻烦来创建唯一的文件名,然后将它们读入并在之后删除它们。但我还是实现了它。

service.exportFile(ids, writer, properties)

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

于 2013-07-05T07:52:47.083 回答