AWS Ruby SDK核心:将文件上传到S3

5

我想使用AWS-SDK-CORE ruby SDK将文件(任何文件,可以是 .txt、.mp4、.mp3、.zip、.tar 等)上传到 AWS S3。

以下是我的代码:

require 'aws-sdk-core'
Aws.config = {
  :access_key_id => MY_ACCESS_KEY
  :secret_access_key => MY_SECRET_KEY,
  :region => 'us-west-2'
}

s3 = Aws::S3.new
resp = s3.put_object(
  :bucket => "mybucket",
  :key => "myfolder/upload_me.sql",
  :body => "./upload_me.sql"
)

现在,上面的代码运行并创建了一个名为myfolder/upload_me.sql的密钥,其中只写了一行,即./upload_me.sql,这是错误的。文件upload_me.sql有几行内容。
期望的行为是将文件upload_me.sql上传到S3作为mybucket/myfolder/upload_me.sql。但实际上它只向mybucket/myfolder/upload_me.sql中写入了一行,即./upload_me.sql 现在,如果我省略以下:body部分:
s3 = Aws::S3.new
resp = s3.put_object(
  :bucket => "mybucket",
  :key => "myfolder/upload_me.sql",
)

然后它只创建一个名为mybucket/myfolder/upload_me.sql的空键,甚至无法下载(即使它被下载,也是无用的)

您能指出我错在哪里吗?

这是put_object方法的ruby-SDK-core文档: http://docs.aws.amazon.com/sdkforruby/api/Aws/S3/V20060301.html#put_object-instance_method

更新: 如果我尝试使用AWS-CLI上传相同的文件,它可以正常上传。这是命令:

aws s3api put-object --bucket mybucket --key myfolder/upload_me.sql --body ./upload_me.sql
4个回答

11

经过一个令人沮丧的周日下午,我终于解决了这个问题。我真正需要的是:body => IO.read("./upload_me.sql")

因此,我的代码看起来像下面这样:

s3 = Aws::S3.new
resp = s3.put_object(
  :bucket => "mybucket",
  :key => "myfolder/upload_me.sql",
  :body => IO.read("./upload_me.sql")
)

1
另一种方法是:
AWS.config(
    :access_key_id => 'MY_ACCESS_KEY',
    :secret_access_key => 'MY_SECRET_KEY',
)

#Set the filename
file_name = 'filename.txt'

#Set the bucket name
s3_bucket_name = 'my bucket name'

#If file has to go in some specific folder
bucket_directory = 'key or folder'

begin
  s3 = AWS::S3.new

  #Check if directory name has provided and Make an object in your bucket for your upload
  if bucket_directory == ''
    bucket_obj = s3.buckets[s3_bucket_name].objects[bucket_directory]
  else
    bucket_obj = s3.buckets[s3_bucket_name].objects["#{bucket_directory}/#{file_name}"]
  end

  # Upload the file
  bucket_obj.write(:file => file_name)
  puts "File was successfully uploaded : #{bucket_obj}"
rescue Exception => e
  puts "There was an error in uploading file: #{e}"
end

工作示例

参考资料


1
变量是将要写入S3的内容。因此,如果您要将文件发送到S3,则需要手动加载类似于File.read(“upload_me.sql”)的内容。
s3 = Aws::S3.new
resp = s3.put_object(
  :bucket => "mybucket",
  :key => "myfolder/upload_me.sql",
  :body => File.read("./upload_me.sql")
)

根据文档,另一种实现此操作的方法是在存储桶上使用写入功能。
s3 = AWS::S3.new
key = File.basename(file_name)
s3.buckets["mybucket"].objects[key].write(:file => "upload_me.sql")

1
“另一种方法”是使用旧版AWS SDK for ruby。它需要require 'aws-sdk'。我正在使用更新的ruby AWS-SDK-CORE,它需要require 'aws-sdk-core'。此外,旧版SDK将对象定义为AWS::S3.new,而新版SDK将对象定义为Aws::S3.new。对于非文本文件,使用“File.read”的第一种解决方案可能无法正常工作。感谢您的时间。 - slayedbylucifer
+1. 嘿@Pafjo,你的回复让我头脑清晰了。我已经发布了答案。 - slayedbylucifer

0

可能是因为路径是相对路径,所以找不到文件。

这是一种奇怪的行为,界面试图做出太多决策。

我可以向您保证,这个(v3)是有效的:

client = Aws::S3::Client.new(...)
client.put_object(
  body: './existing_file.txt',
  bucket: 'kick-it',
  key: 'test1.txt'
) # kick-it:/test1.txt contains the same as the contents of existing_file.txt

client.put_object(
  body: './non_existing_file.txt',
  bucket: 'kick-it',
  key: 'test2.txt'
) # kick-it:/test2.txt contains just the string './non_existing_file.txt'

如果你问我,使用相同的body来处理两种情况是一个糟糕的决定。


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