使用 ServletOutputStream 在 Java servlet 中写入非常大的文件,而不会出现内存问题
我正在使用IBM Websphere Application Server v6和Java 1.4,并尝试将大型CSV文件写入用户下载。目前,文件的范围从50-750MB不等。ServletOutputStream
较小的文件不会造成太大的问题,但是对于较大的文件,它似乎被写入堆中,然后导致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