2012-02-14 54 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") 
工作
相关问题