2013-03-05 121 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

相關問題