【发布时间】:2010-10-15 16:14:50
【问题描述】:
我正在使用 IBM Websphere Application Server v6 和 Java 1.4 并尝试将大型 CSV 文件写入ServletOutputStream 以供用户下载。目前文件大小在 50-750MB 之间。
较小的文件不会造成太大的问题,但对于较大的文件,它似乎正在被写入堆中,这会导致 OutOfMemory 错误并关闭整个服务器。
这些文件只能通过 HTTPS 提供给经过身份验证的用户,这就是为什么我通过 Servlet 为它们提供服务,而不是仅仅将它们粘贴在 Apache 中。
我正在使用的代码是(在此周围删除了一些绒毛):
resp.setHeader("Content-length", "" + fileLength);
resp.setContentType("application/vnd.ms-excel");
resp.setHeader("Content-Disposition","attachment; filename=\"export.csv\"");
FileInputStream inputStream = null;
try
{
inputStream = new FileInputStream(path);
byte[] buffer = new byte[1024];
int bytesRead = 0;
do
{
bytesRead = inputStream.read(buffer, offset, buffer.length);
resp.getOutputStream().write(buffer, 0, bytesRead);
}
while (bytesRead == buffer.length);
resp.getOutputStream().flush();
}
finally
{
if(inputStream != null)
inputStream.close();
}
FileInputStream 似乎没有引起问题,就像我写入另一个文件或只是完全删除写入内存使用似乎不是问题一样。
我在想的是resp.getOutputStream().write 被存储在内存中,直到数据可以发送到客户端。所以整个文件可能会被读取并存储在resp.getOutputStream() 中导致我的内存问题和崩溃!
我已经尝试缓冲这些流,还尝试使用来自java.nio 的通道,但这些似乎都不会对我的内存问题产生任何影响。我还在循环的每次迭代和循环之后刷新了一次 OutputStream,但这没有帮助。
【问题讨论】:
-
尝试设置这个 Websphere Web 容器定制属性 - com.ibm.ws.webcontainer.channelwritetype=sync 详细信息在这里 - publib.boulder.ibm.com/infocenter/wasinfo/v6r0/index.jsp?topic=/…
标签: java servlets stream websphere