我正在运行一个脚本,在已经上传到S3存储桶后,会更新某些S3对象上的元数据字段。在初始化时,我通过检查文件名来设置内容类型。
def save_to_amazon(file, s3_object, file_name, meta_path)
puts "uploaded #{file} to Amazon S3"
content_type = set_content_type(file_name)
s3_object.write(file.get_input_stream.read, :metadata => { :folders => meta_path}, :content_type => content_type)
end
此时,S3内容类型适用于这些对象。我稍后更新元数据时会出现问题。我运行这样的事情:
s3_object.metadata['folders'] = "some string"
此时,我在更新元数据后运行s3_objects.content_type
时返回一个空字符串。
s3_object.content_type =
不可用。
据我所知,在阅读Rdoc时,上传S3文件后无法分配内容类型。我尝试使用像
这样的元数据方法s3.object.metadata['content_type'] = "some string"
s3.object.metadata['content-type'] = "some string"
这两个似乎都分配了一个新的自定义元数据属性,而不是更新对象的mime类型。
有没有办法设置,或者我是否需要再次完全重新上传文件?
答案 0 :(得分:8)
详细说明tkotisis响应,这是我使用copy_to更新内容类型的方法。您可以使用s3object.head [:metadata]提取现有元数据,将其复制为引用here。
amazon_bucket.objects.each do |ob|
metadata = ob.head[:metadata]
content_type = "foo/bar"
ob.copy_to(ob.key, :metadata => metadata, :content_type => content_type)
end
修改强>
amazon_bucket.objects.each do |ob|
metadata = ob.metadata
content_type = "foo/bar"
ob.copy_to(ob.key, :metadata{:foo => metadata[:foo]}, :content_type => content_type)
end
答案 1 :(得分:6)
您的示例代码仅修改您的内存中对象。 要修改实际S3对象的元数据,请发出一个复制请求,其目标键是当前对象的一个。
修改强>
使用复制操作,您可以通过复制和重命名对象 删除原始的。
复制对象时,您可能决定更新一些对象 元数据值。例如,如果源对象配置为 使用标准存储,您可以选择使用减少冗余 存储对象副本。你也可能决定改变一些 源对象上存在的用户定义的元数据值。注意 如果您选择更新任何对象的用户可配置 复制期间的元数据(系统或用户定义),然后您必须 显式指定所有用户可配置的元数据,即使您是 仅更改源上存在的一个元数据值 请求中的对象。
我没有尝试过,但使用Ruby SDK可能是通过
实现的- (S3Object) copy_to(target, options = {})
答案 2 :(得分:2)
确保将ACL设置为:public read,否则复制后文件将不可用。
这对我有用:
bucket.objects.with_prefix('my_assets').each do |obj|
metadata = obj.head[:metadata]
content_type = "application/pdf"
obj.copy_to(obj.key, :metadata => metadata, :content_type => content_type)
obj.acl = :public_read
end
答案 3 :(得分:2)
我正在使用宝石“aws-sdk”,“〜> 2”(2.2.3)
假设您有一个没有设置内容类型的当前文件(默认情况下,Content-type将被设置为“binary / octet-stream”)
如果您使用 RestClient ,如下所示:
对象意味着Aws :: S3 :: Object
bucket = Aws::S3::Bucket.new(bucket_name)
object = bucket.object(key)
RestClient.head(object.presigned_url(:head)) do |resp|
puts resp.headers
puts resp.headers[:content_type]
end
在我的情况下,我想将内容类型更改为'image / jpeg',当前对象是'binary / octet-stream',这样你就可以
object.copy_from(
object,
content_type: 'image/jpeg',
metadata_directive: 'REPLACE'
)
答案 4 :(得分:1)
虽然不是Ruby我发现this project根据扩展名自动猜测mime类型,并且重置是通过与其他答案所引用的相同的复制方法。它不是非常快,因为它必须复制blob。如果你需要让它更快地发生,你可能会分割工作并通过IronWorker之类的东西并行复制。我做了similar thing for resetting permissions。