2012-12-14 19 views
9

當我爲它工作一個單一的文件做:如何使用S3與sdk將整個「文件夾」複製到另一個路徑?

aws_s3 = AWS::S3.new(S3_CONFIG) 
    bucket = aws_s3.buckets[S3_CONFIG["bucket"]] 

    object = bucket.objects["user/1/photos/image_1.jpg"] 
    new_object = bucket.objects["users/1/photos/image_1.jpg"] 
    object.copy_to new_object, {:acl => :public_read} 

但我想移動整個「/照片」文件夾中拋出No Such Key。可能s3鍵只是每個文件的完整路徑。怎麼做?

aws_s3 = AWS::S3.new(S3_CONFIG) 
    bucket = aws_s3.buckets[S3_CONFIG["bucket"]] 

    object = bucket.objects["user/1/photos"] 
    new_object = bucket.objects["users/1/photos"] 
    object.copy_to new_object, {:acl => :public_read} 

謝謝!

回答

4

難道它:

bucket.objects.with_prefix("user/1/photos").each do |object| 
    ... 
end 
+7

最好爲您的答案提供解釋,而不是簡單地給出代碼。這爲其他用戶具有類似但不完全相同的問題提供了額外的見解。 – Guvante

+0

解釋是使用aws with_prefix ... – Luccas

+0

自動標記爲低質量帖子,沒有注意到您正在回答自己的問題。一種方法是從API文檔或類似文檔(帶鏈接)提供with_prefix用法的引用。但是如果你認爲這個代碼足以回答這個問題,那麼這是你的問題。 – Guvante

0

我需要額外的代碼得到這個工作。基本上砍掉從源頭前綴的基礎,然後添加到目的地前綴:

def copy_files_s3(bucket_name, source, destination) 
    source_bucket = @s3.buckets[bucket_name] 
    source_bucket.objects.with_prefix(source).each do |source_object| 
    new_file_name = source_object.key.dup 
    new_file_name.slice! source 
    new_object = source_bucket.objects["#{destination}#{new_file_name}"] 
    source_object.copy_to new_object, {acl: :public_read} 
    end 
end 
1

A「文件夾」是在S3中的對象,這就是爲什麼你不能用鑰匙得到它,但該文件夾路徑實際上是該文件夾包含的所有對象的鍵的前綴。

另一件重要的事情是,您必須對密鑰進行url編碼,否則最終可能會出現未知的密鑰錯誤。

require 'aws-sdk' 
require 'aws-sdk-s3' 
require 'securerandom' 
require 'uri' 
require "erb" 
include ERB::Util 

def copy_folder(folder, destination) 
    bucket_name = 'your_bucket' 
    credentials = Aws::Credentials.new('key', 'secret') 
    s3_client = Aws::S3::Client.new(region:'the_region', credentials: credentials) 
    enumerate_keys_with_prefix(source).each do |source_object| 
     source_key = url_encode(source_object.key) 
     destination_key = source_object.key.dup.sub(source, "") 
     s3_client.copy_object({bucket: bucket_name, copy_source: bucket_name+'/'+source_key, key: destination+'/'+destination_key, acl: "public-read"}) 
    end 
end 

def enumerate_keys_with_prefix(prefix) 
    bucket_name = 'your_bucket' 
    credentials = Aws::Credentials.new('key', 'secret') 
    s3 = Aws::S3::Resource.new(region:'the_region', credentials:credentials) 
    return s3.bucket(bucket_name).objects(prefix: prefix) 
end 
相關問題