使用Java从服务器下载大文件时出错

问题描述:

我是Java中文件处理的新手。我写了一个应该从服务器上下载文件的代码。 该代码正在处理大小为70 MB的文件。如果大文件被下载,则会引发异常。使用Java从服务器下载大文件时出错

SRVE0260E:服务器无法使用为您的应用程序指定的错误页面来处理下面打印的原始异常。

原始例外: 错误消息:java.lang.OutOfMemoryError 错误代码:500 目标的Servlet:空 错误堆栈: java.lang.OutOfMemoryError “在app.web.webcontroller.webAction.DownloadCsvAction.execute (DownloadCsvAction.java:49)“ ”at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:422)“ ”at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:228 )“org.apache.struts.action.ActionServlet.process(ActionServlet.java:1164)” “org.apache.struts.action.ActionServlet.doGet(ActionServlet.ja va:397)“ ”位于javax.servlet.http.HttpServlet.service(HttpServlet.java:718)“ ”位于javax.servlet.http.HttpServlet.service(HttpServlet.java:831)“ ”at com。 ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1530)“ ”at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1470)“ ”at com.ibm。 ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:131) “ ”在app.systemController.RequestTimerFilter.doFilter_http(RequestTimerFilter.java:73)“ ” 在app.systemController.RequestTimerFilter.doFilter(RequestTimerFilter.java: 61)“ ”at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:188)“ ”at com.ibm.ws.webcont ainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:116)“ ”at com.ibm.ws.webcontainer.filter.WebAppFilterChain._doFilter(WebAppFilterChain.java:77)“ ”at com.ibm.ws.webcontainer。 filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:858)“ ”at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:824)“ ”at com.ibm.ws.webcontainer.servlet。 ServletWrapper.handleRequest(ServletWrapper.java:458)“ ”at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:175)“ ”at com.ibm.ws.webcontainer.servlet.CacheServletWrapper。 handleRequest(CacheServletWrapper.java:91)“ ”at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:862)“ ”at com.ibm.w s.webcontainer.WSWebContainer.handleRequest(WSWebContainer.java:1583)“ ”at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:178)“ ”at com.ibm.ws.http。 channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:455) “ ”在com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewInformation(HttpInboundLink.java:384)“ ” 在COM。 ibm.ws.http.channel.inbound.impl.HttpICLReadCallback.complete(HttpICLReadCallback.java:83)“ ”at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:165)“ “at com.ibm.io.async.AsyncChannelFuture.fireCompletionActions(AsyncChannelFuture.java:161)”com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)“ ” “at com.ibm.io.async.AsyncFuture.completed(AsyncFuture.java:138)” “at com.ibm.io.async.ResultHandler.complete(ResultHandler.java:204)” “at com.ibm .io.async.ResultHandler.runEventProcessingLoop(ResultHandler。java:775)“ ”at com.ibm.io.async.ResultHandler $ 2.run(ResultHandler.java:905)“ ”at com.ibm.ws.util.ThreadPool $ Worker.run(ThreadPool.java:1550 )”

错误页面异常: 错误消息:java.lang.IllegalStateException:SRVE0199E:已经获得的OutputStream 错误代码:0 目标的Servlet:空 错误堆栈: java.lang.IllegalStateException:SRVE0199E:OutputStream中已经获得 “在com.ibm.ws.webcontainer.srt.SRTServletResponse.getWriter(SRTServletResponse.java:719)” “在org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:187)” “在Ø rg.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:175)“ ”at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:262)“ ”at org.apache.jasper。 runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:177)“ ”at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:137)“ ”at com.ibm._jsp._Error500._jspService(_Error500。 javax.servlet.http.HttpServlet.service(HttpServlet.java:831)“ ”java:177)“ ”at com.ibm.ws.jsp.runtime.HttpJspBase.service(HttpJspBase.java:98)“ ” “at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1530)” “at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1470)”(WebAppFilterChain.java:77)“ ”(com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:104)“ ”在com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:858) “ ”在com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:824)“ ” 在COM .ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:458)“ ”at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:175)“ ”at com.ibm .wsspi.webcontainer.servlet.GenericServletWrapper.handleRequest(GenericServletWrapper.java:121)“ ”at com.ibm.ws.jsp.webcontainerext.AbstractJSPExtensionServletWrapper.handleRe任务(AbstractJSPExtensionServletWrapper.java:239)“ ”at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.forward(WebAppRequestDispatcher.java:330)“ ”at com.ibm.ws.webcontainer.webapp.WebApp.sendError( WebApp.java:3209)“ ”at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:987)“ ”at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper。 java:458)“ ”at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:175)“ ”at com.ibm.ws.webcontainer.servlet.CacheServletWrapper.handleRequest(CacheServletWrapper.java: 91)“ ”,位于com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:862)“ ”,位于com.ibm.ws.webcontainer.WSWebContainer。 handleRequest(WSWebContainer.java:1583)“ ”at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:178)“ ”at com.ibm.ws.http.channel.inbound.impl。 HttpInboundLink.handleDiscrimination(HttpInboundLink.java:455)“ ”at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewInformation(HttpInboundLink.java:384)“ ”at com.ibm.ws.http。 channel.inbound.impl.HttpICLReadCallback.complete(HttpICLReadCallback.java:83)“ ”at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:165)“ ”at com.ibm。 io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)“ ”at com.ibm.io.async.AsyncChannelFuture.fireCompletionActions(AsyncChannelFuture。java:161)“ ”at com.ibm.io.async.AsyncFuture.completed(AsyncFuture.java:138)“ ”at com.ibm.io.async.ResultHandler.complete(ResultHandler.java:204)“ “at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:775)” “at com.ibm.io.async.ResultHandler $ 2.run(ResultHandler.java:905)” “at com.ibm .ws.util.ThreadPool $ Worker.run(ThreadPool.java:1550)”

此异常被印刷在所下载的文件,而不是具有原始数据。

response.setHeader("Content-Disposition","attachment;filename=\""+fileName+"\""); 
     response.setContentType("application/octet-stream"); 
     File downloadFile = new File(fileUrl\fileName); 
     OutputStream out = response.getOutputStream(); 
     FileInputStream in = new FileInputStream(downloadFile); 
     int size=(int)downloadFile.length()+1; 
     byte[] buffer = new byte[size]; 
     int length; 
     while ((length = in.read(buffer)) != -1){ 
      out.write(buffer, 0, length); 
     } 
     in.close(); 
     out.flush(); 

也在代码片段中,请告诉我是否有任何方法来优化我的代码以使其更快。

+0

看看这篇文章http://*.com/questions/17627508/outofmemoryerror-when-trying-to-read-write-from-a-huge-text -文件 – 2015-02-12 07:21:55

您创建一个缓冲区,其大小为要传输的文件。对于大文件,您将得到所发生的情况:OutOfMemoryError,因为堆中没有足够的空间来存储那么多数据。

最简单的方法是选择一个较小的缓冲区大小,比如64k。这不应该显着地降低性能:

byte[] buffer = new byte[64 * 1024]; 

此代码杀死你的应用程序:

int size=(int)downloadFile.length()+1; 
byte[] buffer = new byte[size]; 

因为你使用过大的缓冲区,以便JVM会OutOfMemory。你应该把你的文件分成小块,如byte[] buffer = new byte[1024]