[英]how to download large files without memory issues in java
When I am trying to download a large file which is of 260MB from server, I get this error: java.lang.OutOfMemoryError: Java heap space.
当我尝试从服务器下载260MB的大文件时,我收到此错误:
java.lang.OutOfMemoryError: Java heap space.
I am sure my heap size is less than 252MB. 我确信我的堆大小小于252MB。 Is there any way I can download large files without increasing heap size?
有没有办法在不增加堆大小的情况下下载大文件?
How I can download large files without getting this issue? 如何在不解决此问题的情况下下载大文件? My code is given below:
我的代码如下:
String path= "C:/temp.zip";
response.addHeader("Content-Disposition", "attachment; filename=\"test.zip\"");
byte[] buf = new byte[1024];
try {
File file = new File(path);
long length = file.length();
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
ServletOutputStream out = response.getOutputStream();
while ((in != null) && ((length = in.read(buf)) != -1)) {
out.write(buf, 0, (int) length);
}
in.close();
out.close();
There are 2 places where I can see you could potentially be building up memory usage: 我可以看到有两个地方可能会增加内存使用量:
For #1 I would suggest reading directly from the file via FileInputStream
without the BufferedInputStream
. 对于#1,我建议通过
FileInputStream
直接从文件中读取而不使用BufferedInputStream
。 Try this first and see if it resolves your issue. 首先尝试这一点,看看它是否能解决您的问题。 ie:
即:
FileInputStream in = new FileInputStream(file);
instead of: 代替:
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
If #1 does not resolve the issue, you could try periodically flushing the output stream after so much data is written (decrease chunk size if necessary): 如果#1无法解决问题,您可以尝试在写入如此多的数据后定期刷新输出流(如果需要,减少块大小):
ie: 即:
try
{
FileInputStream fileInputStream = new FileInputStream(file);
byte[] buf=new byte[8192];
int bytesread = 0, bytesBuffered = 0;
while( (bytesread = fileInputStream.read( buf )) > -1 ) {
out.write( buf, 0, bytesread );
bytesBuffered += bytesread;
if (bytesBuffered > 1024 * 1024) { //flush after 1MB
bytesBuffered = 0;
out.flush();
}
}
}
finally {
if (out != null) {
out.flush();
}
}
Unfortunately you have not mentioned what type out
is. 不幸的是,你还没有提到什么类型的
out
是。 If you have memory issues I guess it is ByteArrayOutpoutStream
. 如果你有内存问题我猜它是
ByteArrayOutpoutStream
。 So, replace it by FileOutputStream
and write the byte you are downloading directly to file. 因此,用
FileOutputStream
替换它,并将您正在下载的字节直接写入文件。
BTW, do not use read()
method that reads byte-by-byte. 顺便说一句,不要使用逐字节读取的
read()
方法。 Use read(byte[] arr)
instead. 请改用
read(byte[] arr)
。 This is much faster. 这要快得多。
First you can remove the (in != null) from your while statement, it's unnecessary. 首先,您可以从while语句中删除(in!= null),这是不必要的。 Second, try removing the BufferedInputStream and just do:
其次,尝试删除BufferedInputStream,然后执行:
FileInputStream in = new FileInputStream(file);
There's nothing wrong (in regard to memory usage) with the code you're show. 使用您显示的代码没有任何错误(关于内存使用情况)。 Either the servlet container is configured to buffer the entire response (look at the
web.xml
configuration), or the memory is being leaked elsewhere. servlet容器配置为缓冲整个响应(查看
web.xml
配置),或者内存泄漏到其他地方。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.