从Web浏览器上传大型文件并传输到Amazon S3

时间:2013-11-24 06:07:38

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

我们目前有一个小型网络应用,其中一部分是文件上传。目前,我们在客户端上使用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时都会返回PartETag。那么,我的下一个问题是如何在从浏览器上传块时保存所有这些PartETag?我的第一个想法是我可以在响应中发送每个块的PartETag,然后存储那些客户端。我不确定是否有办法知道上一个块的上传时间,以便我可以发送所有这些PartETag个。如果没有,我只需要发送我每次都拥有的所有内容,然后只有最后一个请求会使用它们。这一切对我来说似乎都有些蠢。

所以,我认为有人必须先处理这个问题。这样做有一个好的,标准的方法吗?

我考虑在应用服务器上构建文件,然后将其发送到S3,但是对于多个应用服务器,这些块不能保证在同一个地方结束。

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

我感谢任何人都能提供的任何帮助。

2 个答案:

答案 0 :(得分:1)

尝试我们的 IaaS 解决方案:

https://uploadcare.com

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

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

答案 1 :(得分:0)

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

  

我遇到的问题是我需要以某种方式知道uploadId   块。当我从中获取InitiateMultipartUploadResult时,我有它   初始化上传,但我如何将其与之关联   出现的块?

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

  

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

这似乎是一个好主意,然后在'ChunkUploaded'上更改上面的查询字符串以添加刚刚收到的PartETag,从而转移所有先前收到的PartETag每个请求。不确定是否可以更改块之间的查询字符串,或者如果您可以在上载下一个块之前同步执行某些处理,但我认为值得一试。

  

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

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

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

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