简体   繁体   English

如何在java中下载没有内存问题的大文件

[英]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: 我可以看到有两个地方可能会增加内存使用量:

  1. In the buffer reading your input file. 在缓冲区中读取输入文件。
  2. In the buffer writing to your output stream (HTTPOutputStream?) 在缓冲区写入输出流(HTTPOutputStream?)

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.

相关问题 使用 ServletOutputStream 在 Java servlet 中写入非常大的文件而不会出现内存问题 - Using ServletOutputStream to write very large files in a Java servlet without memory issues 在 Java 中将大图像加载为没有 memory 问题的缩略图? - Loading large images as thumbnails without memory issues in Java? 如何获取大型JSON使用REST模板Spring MVC在java中没有内存问题 - How to get large JSON Using REST template Spring MVC without memory issues in java 在不读取Java内存的情况下读取(可能很大)文本文件? - Reading (Potentially Large) Text Files without Reading to Memory in Java? 如何在 Java 中的已排序大文本文件中找到差异(基于行)而不将它们全部加载到 memory 中? - How to find difference (line-based) in sorted large text files in Java without loading them in full into memory? 使用Java下载大文件 - Download Large Files using java 如何在java中下载大型文件(大小> 50MB) - How to download large sized Files (size > 50MB) in java 如何使用angular.js和java使用大文件逐块下载大文件 - how to download large files chunk by chunk using large files using angular.js and java 使用大字节数组下载大文件会导致“内存不足” - Download large files using large byte array causes “Out of memory” 用Java进行内存管理,加载大文件,如何取消分配对象? - Memory management in Java, loading large files, how to deallocate objects?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM