【问题标题】:GAE Upload large file to blobstore from an URLGAE 从 URL 将大文件上传到 blobstore
【发布时间】:2013-02-23 08:26:08
【问题描述】:

我想将 30MB 到 2GB 的大型视频文件上传到具有访问此文件的外部 URL 的 Blob 存储。

到目前为止,我尝试了类似的方法,但它不适用于大文件,我认为是因为 32MB 的限制:

    //InputStream is = new URL(getUrlThumbnailFullSize(wistiaResponse)).openStream();
    HttpURLConnection con = (HttpURLConnection) new URL("URL of the file here").openConnection();
    con.setConnectTimeout(0);
    con.connect();
    InputStream is = con.getInputStream();
    //create file service to upload the video to the blob store
    FileService fileService = FileServiceFactory.getFileService();
    //create the App Engine File; assign MIME type and name
    AppEngineFile file = fileService.createNewBlobFile("content type here", "file name here");
    //lock when uploading file
    boolean lock = true;
    //open channel
    FileWriteChannel writeChannel = fileService.openWriteChannel(file, lock);
    //upload file
    writeChannel.write(ByteBuffer.wrap(IOUtils.toByteArray(is)));
    writeChannel.closeFinally();
    //release the lock
    lock = false;
    //get blob key
    BlobKey blobKey = FileServiceFactory.getFileService().getBlobKey(file);

但我有以下堆栈跟踪:

严重:com.google.appengine.api.urlfetch.ResponseTooLargeException: 来自 url 的响应 http://embed.wistia.com/deliveries/a0f8dc8ed210b53152af601eb0af40d76cd2929f.bin 太大了。在 com.google.appengine.api.urlfetch.URLFetchServiceImpl.fetch(URLFetchServiceImpl.java:57) 在 com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler$Connection.fetchResponse(URLFetchServiceStreamHandler.java:417) 在 com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler$Connection.getInputStream(URLFetchServiceStreamHandler.java:296) 在 controller.CtrlWistia.download(CtrlWistia.java:149) 在 控制器.CtrlWistia.ajax(CtrlWistia.java:89) 在 控制器.CtrlAjax.main(CtrlAjax.java:66) 在 vidaao.AjaxServlet.doPost(AjaxServlet.java:37) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:637) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:717) 在 org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511) 在 org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166) 在 org.tukey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain.java:176) 在 org.tukey.web.filters.urlrewrite.RuleChain.doRules(RuleChain.java:145) 在 org.tukey.web.filters.urlrewrite.UrlRewriter.processRequest(UrlRewriter.java:92) 在 org.tukey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:394) 在 org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 在 com.google.appengine.api.socket.dev.DevSocketFilter.doFilter(DevSocketFilter.java:74) 在 org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 在 com.google.appengine.tools.development.ResponseRewriterFilter.doFilter(ResponseRewriterFilter.java:123) 在 org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 在 com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:34) 在 org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 在 com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:61) 在 org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 在 com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43) 在 org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 在 com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:125) 在 org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 在 com.google.appengine.tools.development.BackendServersFilter.doFilter(BackendServersFilter.java:97) 在 org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 在 org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388) 在 org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) 在 org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182) 在 org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765) 在 org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418) 在 com.google.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:94) 在 org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) 在 com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:409) 在 org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) 在 org.mortbay.jetty.Server.handle(Server.java:326)

【问题讨论】:

    标签: java google-app-engine


    【解决方案1】:

    大文件上传请使用blobstoreService.createUploadUrl

    [更新] 啊,我想我明白了。 目前这是不可能的,因为 URLFetch 服务有 32MB 的响应大小限制。作为一种解决方法,您可以从客户端 javascript 中的 URL 下载文件并使用 blobstore 服务创建的上传 URL 上传它吗?

    [更新] 好的,您需要在服务器端实现这一点,我从问题中并不清楚。所以请忘记 createUploadUrl。

    如果服务器支持 Range 标头,您可以多次请求较小的数据块并将它们存储为单独的 blob 存储对象,以及所需的元数据,如文件名、mimetype、blob 键列表等。

    此外,如果您想将它们合并到一个文件中,您可以使用 Google Cloud Storage。使用Resumable upload option,您可以将数据块多次发送到 Google Cloud Storage。

    【讨论】:

    • 所以请提出另一个问题。
    • 好吧,我不知道是否可以在 JavaScript 中下载 2GB 文件并在使用 blobstoreService.createUploadUrl 后上传。并在推送队列中进行,以避免超过 30 秒的时间。这是你提议的,因为我认为你不能在推送队列中执行任何 JS 对吗?你有任何示例代码这样做,因为我似乎不可能吗?
    猜你喜欢
    • 1970-01-01
    • 2014-10-10
    • 2015-06-18
    • 1970-01-01
    • 2015-12-11
    • 2014-06-27
    • 2012-08-04
    • 1970-01-01
    • 2014-01-06
    相关资源
    最近更新 更多