我们正在从Windows计算机通过Ruby AWS SDK(v2)将各种文件上传到S3。我们已经使用Ruby 1.9进行了测试。我们的代码运行正常,除非遇到大文件,抛出内存不足错误。
首先,我们使用以下代码将整个文件读入内存:
:body => IO.binread(filepath),
然后在Googling之后,我们发现有一些方法可以使用Ruby读取文件:
:body => File.open(filepath, 'rb') { |io| io.read },
但是,此代码无法解决问题,我们找不到特定的S3(或相关)示例,该示例显示了如何读取文件并将其分块传递给S3。整个文件仍被加载到内存中,大文件抛出内存不足错误。
我们知道我们可以将文件拆分为多个块,然后使用AWS分段上传将其上传到S3,但是,如果可能的话,首选避免这种情况(尽管这是唯一的方法,但可以)。
我们的代码示例如下。批量读取文件,避免内存不足错误并上传到S3的最佳方法是什么?
require 'aws-sdk'
filepath = 'c:\path\to\some\large\file.big'
bucket = 's3-bucket-name'
s3key = 'some/s3/key/file.big'
accesskeyid = 'ACCESSKEYID'
accesskey = 'ACCESSKEYHERE'
region = 'aws-region-here'
s3 = Aws::S3::Client.new(
:access_key_id => accesskeyid,
:secret_access_key => accesskey,
:region => region
)
resp = s3.put_object(
:bucket => bucket,
:key => s3key,
:body => File.open(filepath, 'rb') { |io| io.read },
)
请注意,我们没有达到S3 5GB的限制,例如1.5GB的文件就是这种情况。
适用于Ruby(aws-sdk
gem)的v2 AWS开发工具包支持直接通过网络流式传输对象,而无需将其加载到内存中。您的示例仅需进行较小的更改即可:
File.open(filepath, 'rb') do |file|
resp = s3.put_object(
:bucket => bucket,
:key => s3key,
:body => file
)
end
之所以有效,是因为它允许SDK调用#read
每次传递少量字节的文件对象。#read
在没有第一个参数的情况下调用Ruby IO对象(例如文件)会将整个对象读入内存,并将其作为字符串返回。这就是导致您的内存不足错误的原因。
也就是说,aws-sdk
gem提供了另一个更有用的界面,用于将文件上传到Amazon S3。此替代界面会自动:
一个简单的例子:
# notice this uses Resource, not Client
s3 = Aws::S3::Resource.new(
:access_key_id => accesskeyid,
:secret_access_key => accesskey,
:region => region
)
s3.bucket(bucket).object(s3key).upload_file(filepath)
这是aws-sdk
资源接口的一部分。这里有很多有用的实用程序。Client类仅提供基本的API功能。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句