【问题标题】:Uploading large files from web browser and transferring to Amazon S3从 Web 浏览器上传大文件并传输到 Amazon S3
【发布时间】:2023-03-23 19:36:01
【问题描述】:

我们目前有一个小型网络应用程序,其中一部分是文件上传。目前我们在客户端上使用Plupload 启用分块以允许上传大文件。文件保存在应用服务器上,并在出现时附加块。

现在我们将转移到Amazon S3 进行文件存储,并可以使用多个应用服务器。我发现如何处理这些块很困难。我试图关注their example,但我遇到了问题。我正在尝试的内容如下所示:

UploadPartRequest uploadRequest = new UploadPartRequest()
    .withBucketName(bucket).withKey(key)
    .withUploadId(uploadId).withPartNumber(partNumber)
    .withPartSize(bytes.length)
    .withInputStream(new ByteArrayInputStream(bytes));

s3Client.uploadPart(uploadRequest);

我遇到的问题是我需要以某种方式知道块的uploadId。当我从上传初始化中获得InitiateMultipartUploadResult 时,我就有了它,但是我如何将它与后来出现的块相关联?我想我也许可以在第一个响应时将其发送出去,然后在每个块请求时将其发送回来。这似乎并不遥不可及。

然后我发现,为了完成上传,我需要一个 List<PartETag>,每次上传到 Amazon S3 时都会返回 PartETags。那么,我的下一个问题是如何在从浏览器上传块时保存所有这些PartETags?我的第一个想法是我可以在响应中发送每个块的PartETag,然后存储这些客户端。我不确定是否有办法知道最后一个块何时上传,以便我可以发送所有这些PartETags。如果没有,我只需要每次发送所有我拥有的,然后只有最后一个请求会使用它们。这一切对我来说似乎有点 hacky。

所以,我认为之前必须有人处理过这个问题。有没有一种好的、标准的方法来做到这一点?

我考虑过在应用服务器上构建文件,然后将其发送到 S3,但是对于多个应用服务器,不能保证这些块最终会在同一个位置。

我的另一个想法是在上传期间将所有这些信息存储在数据库中,但我不确定我是否必须在每个块请求中访问数据库。除此之外还有其他选择吗?

感谢任何人提供的任何帮助。

【问题讨论】:

    标签: java file-upload amazon-s3 plupload large-file-upload


    【解决方案1】:

    试试我们的 IaaS 解决方案:

    https://uploadcare.com

    它支持最大 5GB 的文件大小。这是一篇关于使用我们的系统上传大文件的成功用例的文章:

    https://community.skuidify.com/skuid/topics/how_to_upload_large_files_using_uploadcare_com

    【讨论】:

      【解决方案2】:

      如果我错了,请纠正我,但据我了解您的问题,您的网络服务器充当浏览器和客户端之间的代理。

      我遇到的问题是我需要以某种方式知道的 uploadId 块。当我得到 InitiateMultipartUploadResult 从 上传的初始化,但我如何将其与稍后关联 出现的块?

      BeforeUpload 上,您可以添加uploadId 作为查询字符串参数,如this answer

      我的第一个想法是我可以发送每个块的 PartETag 响应,然后存储那些客户端。

      这似乎是个好主意,然后像上面那样在“ChunkUploaded”上更改查询字符串以添加刚刚收到的PartETag,从而将所有先前收到的PartETag 转移到每个请求中。不确定是否可以更改块之间的查询字符串,或者您是否可以在开始上传下一个块之前同步进行一些处理,但我想说的是值得一试。

      我不确定是否有办法知道最后一块是什么时候 上传,以便我可以发送所有这些 PartETag。

      这可以在plupload下载的php示例中找到:plupload向服务器发送两个POST参数

      • chunks :上传的总块数(如果上传未分块,则为 0)
      • chunk : 正在上传的当前块的索引

      最后一个块是chunks==0 || chunk==chunks-1

      【讨论】:

      • 服务器端我知道最后一个块何时上传,但我认为没有办法知道客户端。我决定走 DB 路线,因为我不希望我的客户端代码对服务器在做什么有太多了解。这样,如果我们的存储机制发生变化,我就不必重构客户端代码。感谢您的反馈。
      • @dnc 不客气。顺便说一句,要知道客户端的块数,您可以选择将其作为触发 ChunkUploaded 的响应的一部分传递。
      猜你喜欢
      • 2013-09-06
      • 2010-11-17
      • 1970-01-01
      • 1970-01-01
      • 2013-01-20
      • 1970-01-01
      • 2021-06-10
      • 1970-01-01
      • 2023-01-21
      相关资源
      最近更新 更多