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

时间:2015-02-12 07:15:03

标签: java file file-handling

我是Java中文件处理的新手。我编写了一个代码,可以从服务器下载文件。 该代码适用于大小为70 MB的文件。如果下载大文件,则会抛出异常。

  

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

     

原始例外:   错误消息:java.lang.OutOfMemoryError   错误代码:500   目标Servlet:null   错误堆栈:   java.lang.OutOfMemoryError        "在app.web.webcontroller.webAction.DownloadCsvAction.execute(DownloadCsvAction.java:49)"        "在org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:422)"        "在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.java:397)"        "在javax.servlet.http.HttpServlet.service(HttpServlet.java:718)"        "在javax.servlet.http.HttpServlet.service(HttpServlet.java:831)"        "在com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1530)"        "在com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1470)"        "在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)"        "在com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:188)"        "在com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:116)"        "在com.ibm.ws.webcontainer.filter.WebAppFilterChain._doFilter(WebAppFilterChain.java:77)"        "在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)"        "在com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:175)"        "在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)"        "在com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:178)"        "在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)"        "在com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:165)"        "在com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)"        "在com.ibm.io.async.AsyncChannelFuture.fireCompletionActions(AsyncChannelFuture.java:161)"        "在com.ibm.io.async.AsyncFuture.completed(AsyncFuture.java:138)"        "在com.ibm.io.async.ResultHandler.complete(ResultHandler.java:204)"        "在com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:775)"        "在com.ibm.io.async.ResultHandler $ 2.run(ResultHandler.java:905)"        "在com.ibm.ws.util.ThreadPool $ Worker.run(ThreadPool.java:1550)"

     

错误页面例外:   错误消息:java.lang.IllegalStateException:SRVE0199E:已获取OutputStream   错误代码:0   目标Servlet:null   错误堆栈:   java.lang.IllegalStateException:SRVE0199E:已获取OutputStream        "在com.ibm.ws.webcontainer.srt.SRTServletResponse.getWriter(SRTServletResponse.java:719)"        "在org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:187)"        "在org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:175)"        "在org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:262)"        "在org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:177)"        "在org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:137)"        "在com.ibm._jsp._Error500._jspService(_Error500.java:177)"        "在com.ibm.ws.jsp.runtime.HttpJspBase.service(HttpJspBase.java:98)"        "在javax.servlet.http.HttpServlet.service(HttpServlet.java:831)"        "在com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1530)"        "在com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1470)"        "在com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:104)"        "在com.ibm.ws.webcontainer.filter.WebAppFilterChain._doFilter(WebAppFilterChain.java:77)"        "在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)"        "在com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:175)"        "在com.ibm.wsspi.webcontainer.servlet.GenericServletWrapper.handleRequest(GenericServletWrapper.java:121)"        "在com.ibm.ws.jsp.webcontainerext.AbstractJSPExtensionServletWrapper.handleRequest(AbstractJSPExtensionServletWrapper.java:239)"        "在com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.forward(WebAppRequestDispatcher.java:330)"        "在com.ibm.ws.webcontainer.webapp.WebApp.sendError(WebApp.java:3209)"        "在com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:987)"        "在com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:458)"        "在com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:175)"        "在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)"        "在com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:178)"        "在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)"        "在com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:165)"        "在com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)"        "在com.ibm.io.async.AsyncChannelFuture.fireCompletionActions(AsyncChannelFuture.java:161)"        "在com.ibm.io.async.AsyncFuture.completed(AsyncFuture.java:138)"        "在com.ibm.io.async.ResultHandler.complete(ResultHandler.java:204)"        "在com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:775)"        "在com.ibm.io.async.ResultHandler $ 2.run(ResultHandler.java:905)"        "在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();

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

2 个答案:

答案 0 :(得分:2)

您可以使用要传输的文件大小创建缓冲区。使用大文件,您将获得正在发生的事情:OutOfMemoryError,因为堆上没有足够的空间来存储那么多数据。

最简单的解决方法是选择较小的缓冲区大小,例如64k。这不应该明显降低性能:

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

答案 1 :(得分:1)

此代码会终止您的应用:

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

因为你使用的缓冲区太大所以JVM将是OutOfMemory。您应该将文件拆分为小块,例如byte[] buffer = new byte[1024]