2013-03-05 73 views
0

我想读取的字节中出存储在谷歌云存储中的文件,并在一个HTTP POST请求发送,但我去这个例外有较大的文件java.lang.OutOfMemoryError:Java堆空间 - blobstoreService

唯一的例外是在这条线扔:代码与小文件工作

writer.write(blobstoreService.fetchData(new BlobKey(video.getBlobkey()), start, end)); 

这是我的代码:

URLConnection connection = new URL("http://myurl.com/").openConnection(); 
    //set time out to infinite 
    connection.setConnectTimeout(0); 
    connection.setDoOutput(true); 
    connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); 
    BufferedOutputStream writer = null; 
    OutputStream output = connection.getOutputStream(); 
    writer = new BufferedOutputStream(output); // true = autoFlush, important! 

    //........ 

    BlobInfoFactory blobInfoFactory = new BlobInfoFactory(); 
    BlobInfo blobInfo = blobInfoFactory.loadBlobInfo(new BlobKey(video.getBlobkey())); 
    Long blobSize = blobInfo.getSize(); 
    //max read on fetch 
    long maxReadFetch = 1015807; 
    //read the file in one time temporary 
    long i = 0; 
    long start = 0; 
    long end = 0; 
    while(i < blobSize) { 
     start = i; 
     end = i + maxReadFetch; 
     //determine end 
     if(end > blobSize) { 
      end = blobSize; 
     } else { 
      end--; 
     } 
     writer.write(blobstoreService.fetchData(new BlobKey(video.getBlobkey()), start, end)); 

     i += maxReadFetch; 
    } 
    writer.flush(); // Important! Output cannot be closed. Close of writer will close output as well. 
} finally { 
    if (input != null) try { input.close(); } catch (IOException logOrIgnore) {} 
} 

堆栈跟踪:

Uncaught exception from servlet java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:2961) at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:111) at com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler$Connection$BufferingOutputStream.write(URLFetchServiceStreamHandler.java:460) at java.io.BufferedOutputStream.write(BufferedOutputStream.java:122) at java.io.FilterOutputStream.write(FilterOutputStream.java:97) at controller.CtrlWistia.upload(CtrlWistia.java:200) at controller.CtrlWistia.add(CtrlWistia.java:126) at controller.CtrlWistia.ajax(CtrlWistia.java:79) at controller.CtrlAjax.main(CtrlAjax.java:66) at vidaao.AjaxServlet.doPost(AjaxServlet.java:37) at javax.servlet.http.HttpServlet.service(HttpServlet.java:637) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166) at org.tuckey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain.java:176) at org.tuckey.web.filters.urlrewrite.RuleChain.doRules(RuleChain.java:145) at org.tuckey.web.filters.urlrewrite.UrlRewriter.processRequest(UrlRewriter.java:92) at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:394) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:125) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388) at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182) at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765) at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418) at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:266) at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)

回答

1

注意,即使你每次读小于1MB,你正在写数据到的OutputStream,直到您提交请求其保存在内存中。

按照docs

App Engine's implementation of URLConnection does not maintain a persistent connection with the remote host. When the app sets request data or writes to the output stream, the request data is kept in memory. When the app accesses any data about the response, such as getting the input stream (or calling the connect() method), App Engine calls the URL Fetch service with the request data, gets the response, closes the connection and returns the response data.

+0

哦确定...你有什么解决办法在此之前发送的数据? – 2013-03-05 18:12:33

+0

这取决于您使用的提供商。这是S3的答案http://stackoverflow.com/questions/8495167/how-to-upload-file-to-s3-from-gae-a-horror-story – 2013-03-05 18:38:11

+0

噢好吧,我的供应商不会接受这个。太糟糕了,我必须尝试一种完全不同的方法。感谢您的帮助。 – 2013-03-05 20:05:59

相关问题