【问题标题】:Can't Download large files in html request无法在 html 请求中下载大文件
【发布时间】:2014-02-03 15:09:59
【问题描述】:

我的问题是,我无法下载大于 100mb 的文件,我怀疑是 html 请求

这是我回复中的 setHeader

HttpServletResponse response = (HttpServletResponse) requestContext.getExternalContext().getNativeResponse();
            response.setContentType("application/octet-stream");        
            response.setHeader("Content-Disposition", "attachment; filename=\""+fileName+"\"");
            response.setHeader("Pragma", "public");
            response.setHeader("Cache-control", "private");

这是读取文件的流声明

ServletOutputStream sos = response.getOutputStream();   
                sos.flush();
                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                String str = br.readLine();
                while (str != null) {                                           
                    sos.write(str.getBytes());
                    sos.write(13);
                    sos.write(10);
                    str = br.readLine();
                }

这个“while”适用于小文件,但在大文件的情况下,似乎会话丢失了,因为我错过了调试并且不会在下一个断点处停止。 有什么办法可以防止执行失误

【问题讨论】:

  • 你有异常吗?如果是这样,请发布堆栈跟踪。
  • 我无法发布异常,因为服务器中没有发生异常。连接在“while”内丢失

标签: java web-services servlets filestream session-timeout


【解决方案1】:

问题很可能是图像的字节数据没有换行符,并且您在尝试读取一行时内存不足。您需要创建一个固定大小的缓冲区并直接复制字节。像这样的:

ServletOutputStream sos = response.getOutputStream();
sos.flush();
try {
    byte[] buf = new byte[1000];
    while (true) {
        int r = is.read(buf);
        if (r == -1)
            break;
        sos.write(buf, 0, r);
    }
} finally {
    try{is.close();}catch(Exception e){}
    try{sos.close();}catch(Exception e){}
}

【讨论】:

  • 我在我的 websphere 中找到此日志 1TISIGINFO Dump Event "systhrow" (00040000) 收到详细信息 "java/lang/OutOfMemoryError" 需要更多内存。 THX 全部
  • 是的,但是如果您使用上面的代码,您将不需要更多内存,因为您不会将图像加载到内存中;您将以 1kb 的大小将其读出给客户端。
  • 我们需要在读取特定字节后从 ServletOutputStream 中刷新数据。可能代码适用于小文件,但存在大文件出错的机会。请添加一个 'sos.flush();'读取每 10kB 数据后。尝试使用 2GB 文件。您可以看到如果不实现 flush() 方法,代码将失败。再次尝试使用 flush() 实现的相同方法。
【解决方案2】:

每次读取一些数据后,在while循环中刷新输出流对象。您可以设置一个长值并检查。如果达到该限制,您可以刷新输出流对象中的数据,以便系统将刷新大量数据并释放为此分配的内存,因此不会出现内存不足错误。

ServletOutputStream sos = response.getOutputStream();
   long byteRead = 0;
   try {
       byte[] buf = new byte[8291];
       while (true) {
         int r = is.read(buf);
         if (r == -1)
         break;
         sos.write(buf, 0, r);
         byteRead +=r;
         if(byteRead > 1024*1024){ //flushes after 1mb
           byteRead = 0;
           sos.flush();
         }

      }
    } finally {
    if(sos != null){
      sos.flush();
    }
    try{is.close();}catch(Exception e){}
    try{sos.close();}catch(Exception e){}
 }

【讨论】:

    猜你喜欢
    • 2021-08-21
    • 2013-05-17
    • 2013-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多