如何将公共S3文件列表复制到私有S3存储桶

时间:2016-06-17 04:19:46

标签: ruby-on-rails ruby-on-rails-4 amazon-s3

在rails中,以及使用aws-sdk gem的(例如5k文件),将在S3(而不是我的帐户)上托管的公共文件列表复制到我的私有存储桶中的最简单方法是什么?我想保留相同的文件和路径名称。

示例:

http://target.com.s3.amazonaws.com/assets/videos/abc123.mp4 (public)

http://myexample.com.s3.amazonaws.com/assets/videos/abc123.mp4 (private)

我想将文件读入内存并直接流入S3。我的托管服务提供商(Heroku)没有磁盘空间。这些文件是MP4,大小约为3-4MB。

这是我的方法(UNTESTED):

vid_file = 'http://example.com.s3.amazonaws.com/assets/videos/abc123.mp4'
vid_response = HTTParty.get(vid_file)

if vid_response.code == 200

  filename = File.basename(vid_file) # TOOD - fix to include s3 folder before object filename

  s3 = Aws::S3::Resource.new(region: ENV['AWS_REGION'])
  obj = s3.bucket(ENV['S3_BUCKET']).object(filename)
  obj.put(body: vid_response.body)
end

然而,SDK是指导AWS在S3存储桶之间执行内部复制的一种方式,虽然我没有第一个存储桶的密钥(但对象是公共的)?如果不是,我的上述方法是否正确(流入内存,发布到S3)?

2 个答案:

答案 0 :(得分:0)

如果您知道文件名模式的一个简单解决方案是使用类似wget的东西,然后使用ruby s3客户端上传到您的私有存储桶。我明白为什么你会想要使用内存而不是硬盘,但老实说假设你有几个免费的互联网连接可能是瓶颈。

答案 1 :(得分:0)

1)公共S3对象的“内部副本”没有sdk功能到私有S3存储桶。

2)以下源代码工作,它保持相同的S3目录结构

vid_file = 'http://example.com.s3.amazonaws.com/assets/videos/abc123.mp4'
vid_response = HTTParty.get(vid_file)

if vid_response.code == 200

  uri_path = URI(vid_url).path 
  uri_path.slice!(0) # slice!(0) removes leading slash, otherwise creates an empty s3 folder

  s3 = Aws::S3::Resource.new(region: ENV['AWS_REGION'])
  obj = s3.bucket(ENV['S3_BUCKET']).object(uri_path)
  obj.put(body: vid_response.body) if !obj.exists?
end