2012-02-14 31 views

回答

6

你是對的,官方的SDK可以讓你修改的對象元數據而無需重新上傳。它的功能是copy the object,但這是在服務器上,所以你不需要下載文件並重新上傳。

一個包裝很容易實現,像

bucket.objects.each do |object| 
    object.metadata['content-type'] = 'application/json' 
end 
+0

此處的更多討論:http://groups.google.com/group/ruby-fog/browse_thread/thread/e632fc61405bf04c – 2012-02-21 18:30:43

+2

這隻會添加帶有x-amz-meta-前綴的元數據。是隻添加一個普通的Content-Type元數據的方法嗎? – serengeti12 2013-01-01 09:15:34

4

對於未來的讀者,這是一個使用Ruby的AWS-SDK V1改變的東西的一個完整樣本(另見本Gist的AWS-SDK V2樣品):

# Using v1 of Ruby aws-sdk as currently v2 seems not able to do this (broken?). 
require 'aws-sdk-v1' 

key = YOUR_AWS_KEY 
secret = YOUR_AWS_SECRET 
region = YOUR_AWS_REGION 

AWS.config(access_key_id: key, secret_access_key: secret, region: region) 
s3 = AWS::S3.new 
bucket = s3.buckets[bucket_name] 
bucket.objects.with_prefix('images/').each do |obj| 
    puts obj.key 
    # Add metadata: {} to next line for more metadata. 
    obj.copy_from(obj.key, content_type: obj.content_type, cache_control: 'max-age=1576800000', acl: :public_read) 
end 
+0

您的要點說v2樣本似乎不起作用,並且表明它可能是SDK中的一個錯誤...我認爲您尚未解決它? – scottb 2015-03-10 17:42:44

+0

沒有。只是嘗試與V2的最新版本的要點:) – joost 2015-03-10 19:57:16

+0

V2版本不適用於我。我用我的解決方案評論了要點(重新加載每個文件)。 – 2015-09-01 18:44:25

5

在V2 API,你可以使用Object#copy_from()Object.copy_to():metadata:metadata_directive => 'REPLACE'選項,而從S3下載該更新對象的元數據。

Joost's gist的代碼引發此錯誤:

Aws::S3::Errors::InvalidRequest: This copy request is illegal because it is trying to copy an object to itself without changing the object's metadata, storage class, website redirect location or encryption attributes.

這是因爲通過默認AWS忽略與複製操作,因爲它複製的元數據提供的:metadata。如果我們想更新元數據,我們必須設置:metadata_directive => 'REPLACE'選項。

http://docs.aws.amazon.com/sdkforruby/api/Aws/S3/Object.html#copy_from-instance_method

下面是我最近使用進行元數據更新操作全,工作代碼片段:

require 'aws-sdk' 

# S3 setup boilerplate 
client = Aws::S3::Client.new(
    :region => 'us-east-1', 
    :access_key_id => ENV['AWS_ACCESS_KEY'], 
    :secret_access_key => ENV['AWS_SECRET_KEY'], 
) 
s3 = Aws::S3::Resource.new(:client => client) 

# Get an object reference 
object = s3.bucket('my-bucket-name').object('my-object/key') 

# Create our new metadata hash. This can be any hash; in this example we update 
# existing metadata with a new key-value pair. 
new_metadata = object.metadata.merge('MY_NEW_KEY' => 'MY_NEW_VALUE') 

# Use the copy operation to replace our metadata 
object.copy_to(object, 
    :metadata => new_metadata, 

    # IMPORTANT: normally S3 copies the metadata along with the object. 
    # we must supply this directive to replace the existing metadata with 
    # the values we supply 
    :metadata_directive => "REPLACE", 
) 

爲了便於再利用:

def update_metadata(s3_object, new_metadata = {}) 
    s3_object.copy_to(s3_object, 
    :metadata => new_metadata 
    :metadata_directive => "REPLACE" 
) 
end 
+0

要添加緩存控制使用:object.copy_to(object,cache_control:'public,max-age = 333333',metadata_directive:'REPLACE') – 2017-06-15 10:29:48

1

一些搜索後這似乎爲我

obj.copy_to(obj, :metadata_directive=>"REPLACE", :acl=>"public-read",:content_type=>"text/plain") 
工作
相關問題