2015-02-12 62 views
0

我是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://stackoverflow.com/questions/17627508/outofmemoryerror-when-trying-to-read-write-from-a-huge-text -文件 – 2015-02-12 07:21:55

回答

1

您創建一個緩衝區,其大小爲要傳輸的文件。對於大文件,您將得到所發生的情況:OutOfMemoryError,因爲堆中沒有足夠的空間來存儲那麼多數據。

最簡單的方法是選擇一個較小的緩衝區大小,比如64k。這不應該顯着地降低性能:

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

此代碼殺死你的應用程序:

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

因爲你使用過大的緩衝區,以便JVM會OutOfMemory。你應該把你的文件分成小塊,如byte[] buffer = new byte[1024]