使用aws-sdk进行流式上传大文件

3

有没有一种使用aws-sdk流式上传大文件到S3的方法?

我似乎无法弄清楚,但我认为有一种方法。 谢谢

2个回答

6

更新

我的记忆出了问题,我没有正确阅读我初始回答中提到的引用(请参见下文),正如(S3Object,ObjectVersion)write(data,options = {})的API文档所示:

将数据写入S3对象。此方法将尝试智能地选择在一个请求中上传和使用#multipart_upload之间。

[...]您可以将:data或:file作为第一个参数或选项传递。 [我强调]

显然,数据参数是用于流式传输的参数:

:data (Object) — The data to upload. Valid values include:

[...] Any object responding to read and eof?; the object must support the following access methods:

read                     # all at once
read(length) until eof?  # in chunks

If you specify data this way, you must also include the :content_length option.

[...]

:content_length (Integer) — If provided, this option must match the total number of bytes written to S3 during the operation. This option is required if :data is an IO-like object without a size method.

[emphasis mine]

生成的样本片段可能如下所示:
# Upload a file.
key = File.basename(file_name)
s3.buckets[bucket_name].objects[key].write(:data => File.open(file_name), 
    :content_length => File.size(file_name))
puts "Uploading file #{file_name} to bucket #{bucket_name}."

请注意,我还没有实际测试过这个,所以要小心 ;)

初步答案

这在使用AWS SDK for Ruby上传对象中有解释:

上传对象

  1. 通过提供您的AWS凭据创建AWS :: S3类的实例。
  2. 使用AWS :: S3 :: S3Object # write方法,该方法需要数据参数和选项哈希,允许您从文件或流上传数据。 [我的强调]

该页面还包含一个完整的示例,虽然使用的是文件而不是流,但相关片段如下:

# Upload a file.
key = File.basename(file_name)
s3.buckets[bucket_name].objects[key].write(:file => file_name)
puts "Uploading file #{file_name} to bucket #{bucket_name}."

这应该很容易调整为使用流(如果我记得正确,您可能只需要将file_name参数替换为open(file_name) - 但请务必进行验证),例如:

# Upload a file.
key = File.basename(file_name)
s3.buckets[bucket_name].objects[key].write(:file => open(file_name))
puts "Uploading file #{file_name} to bucket #{bucket_name}."

那个程序在几分钟后失败并显示“字符串包含空字节”错误。https://gist.github.com/1990541 - 99miles
@99miles:我的记忆确实出了问题,我已经根据对AWS示例的错误解释进行了更新 - 请注意,我仍然没有实际测试过这个,所以要小心;) - Steffen Opel

1

我不知道你想上传的文件有多大,但对于大文件,'预签名的上传'允许操作浏览器的用户绕过您的服务器直接上传到S3。这可能是你需要的 - 在上传期间释放服务器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接