使用 Java 从服务器下载大文件时出错
Error in Downloading large files from Server using Java
我是 Java 中文件处理的新手。我写了一个代码,应该从服务器下载一个文件。
该代码适用于大小不超过 70 MB.If 的文件,下载大文件会抛出异常。
SRVE0260E: The server cannot use the error page specified for your application to handle the Original Exception printed below.
Original Exception:
Error Message: java.lang.OutOfMemoryError
Error Code: 500
Target Servlet: null
Error Stack:
java.lang.OutOfMemoryError
" at 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)"
" at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1164)"
" at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:397)"
" at javax.servlet.http.HttpServlet.service(HttpServlet.java:718)"
" at 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)"
" at app.systemController.RequestTimerFilter.doFilter_http(RequestTimerFilter.java:73)"
" at app.systemController.RequestTimerFilter.doFilter(RequestTimerFilter.java:61)"
" at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:188)"
" at com.ibm.ws.webcontainer.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.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.run(ResultHandler.java:905)"
" at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1550)"
Error Page Exception:
Error Message: java.lang.IllegalStateException: SRVE0199E: OutputStream already obtained
Error Code: 0
Target Servlet: null
Error Stack:
java.lang.IllegalStateException: SRVE0199E: OutputStream already obtained
" at com.ibm.ws.webcontainer.srt.SRTServletResponse.getWriter(SRTServletResponse.java:719)"
" at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:187)"
" at org.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.java:177)"
" at com.ibm.ws.jsp.runtime.HttpJspBase.service(HttpJspBase.java:98)"
" at 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:104)"
" 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.wsspi.webcontainer.servlet.GenericServletWrapper.handleRequest(GenericServletWrapper.java:121)"
" at com.ibm.ws.jsp.webcontainerext.AbstractJSPExtensionServletWrapper.handleRequest(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)"
" at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:862)"
" at 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.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();
同样在代码片段中,请告诉我是否有任何方法可以优化我的代码以使其更快。
您创建了一个大小与您要传输的文件相同的缓冲区。对于大文件,您将得到发生的事情:OutOfMemoryError,因为您的堆上没有足够的 space 来容纳那么多数据。
最简单的解决方法是选择较小的缓冲区大小,例如 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]
我是 Java 中文件处理的新手。我写了一个代码,应该从服务器下载一个文件。 该代码适用于大小不超过 70 MB.If 的文件,下载大文件会抛出异常。
SRVE0260E: The server cannot use the error page specified for your application to handle the Original Exception printed below.
Original Exception: Error Message: java.lang.OutOfMemoryError Error Code: 500 Target Servlet: null Error Stack: java.lang.OutOfMemoryError " at 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)" " at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1164)" " at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:397)" " at javax.servlet.http.HttpServlet.service(HttpServlet.java:718)" " at 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)" " at app.systemController.RequestTimerFilter.doFilter_http(RequestTimerFilter.java:73)" " at app.systemController.RequestTimerFilter.doFilter(RequestTimerFilter.java:61)" " at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:188)" " at com.ibm.ws.webcontainer.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.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.run(ResultHandler.java:905)" " at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1550)"
Error Page Exception: Error Message: java.lang.IllegalStateException: SRVE0199E: OutputStream already obtained Error Code: 0 Target Servlet: null Error Stack: java.lang.IllegalStateException: SRVE0199E: OutputStream already obtained " at com.ibm.ws.webcontainer.srt.SRTServletResponse.getWriter(SRTServletResponse.java:719)" " at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:187)" " at org.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.java:177)" " at com.ibm.ws.jsp.runtime.HttpJspBase.service(HttpJspBase.java:98)" " at 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:104)" " 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.wsspi.webcontainer.servlet.GenericServletWrapper.handleRequest(GenericServletWrapper.java:121)" " at com.ibm.ws.jsp.webcontainerext.AbstractJSPExtensionServletWrapper.handleRequest(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)" " at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:862)" " at 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.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();
同样在代码片段中,请告诉我是否有任何方法可以优化我的代码以使其更快。
您创建了一个大小与您要传输的文件相同的缓冲区。对于大文件,您将得到发生的事情:OutOfMemoryError,因为您的堆上没有足够的 space 来容纳那么多数据。
最简单的解决方法是选择较小的缓冲区大小,例如 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]