我需要更新所有AmazonS3的云文件中的缓存控制标头。但是,我无法弄清楚如何使用jclouds API执行此操作。 我正在使用apache jclouds插件。我得到了两个相关的答案:
第一个答案是建议使用SwiftKey Api类,这在Grails的jcloud插件中是不可用的。第二个答案是使用AWS java sdk已经有一个grails包装插件https://grails.org/plugin/aws-sdk,但它不支持元数据更新。
答案 0 :(得分:28)
可以通过执行对象复制来更改元数据(请参阅How to update metadata using Amazon S3 SDK):
ObjectMetadata metadataCopy = new ObjectMetadata();
// copy previous metadata
metadataCopy.addUserMetadata("newmetadata", "newmetadatavalue");
CopyObjectRequest request = new CopyObjectRequest(bucketName, existingKey, bucketName, existingKey)
.withNewObjectMetadata(metadataCopy);
amazonS3Client.copyObject(request);
这是否在哲学上是一个“更新”由你来决定。
答案 1 :(得分:20)
你不能:
每个Amazon S3对象都有数据,密钥和元数据。对象键(或 key name)唯一标识存储桶中的对象。对象元数据 是一组名称 - 值对。您可以在此时设置对象元数据 你上传它。 上传对象后,无法修改对象 元数据。修改对象元数据的唯一方法是制作副本 对象并设置元数据。
http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html
答案 2 :(得分:0)
答案 3 :(得分:0)
就我而言,我关心对象的版本,复制会创建一个新版本。我决定使用可变的元数据创建一个并行的“隐藏”对象。例如,如果我有/foo/bar/baz
,那么我将创建/foo/bar/.baz
。
答案 4 :(得分:0)
如其他答案所述,可以发出“复制”请求,覆盖现有记录。
s3_client.copy_object({
bucket: BUCKET, # Destination
key: KEY, # Destination
copy_source: "/#{BUCKET}/#{KEY}", # Source
content_type: "text/html; charset=utf8", # Metadata update
metadata_directive: "REPLACE"
})
答案 5 :(得分:-1)
截至2018年3月,最新版本的AWS SDK for .NET Core已更改。它现在使用异步编程。许多方法签名已经改变。虽然如果没有Dan建议的对象复制解决方案仍然无法更改元数据,那么这样做的代码就有了。
我的解决方案是使用修改后的元数据更新现有S3对象。
以下内容适用于我更新单个元数据值(基于键值和新值)。我有两个用于设置元数据的循环,但它可以优化为只有一个:
string fileContents = string.Empty;
Dictionary<string, string> fileMetaData = null;
GetObjectRequest request = new GetObjectRequest
{
BucketName = bucketName,
Key = setKeyName
};
var response = await s3Client.GetObjectAsync(request);
// Read the contents of the file
using (var stream = response.ResponseStream)
{
// Get file contents
TextReader tr = new StreamReader(stream);
fileContents = tr.ReadToEnd();
}
// Create the File Metadata collection
fileMetaData = new Dictionary<string, string>();
foreach (string metadataKey in response.Metadata.Keys)
{
fileMetaData.Add(metadataKey, response.Metadata[metadataKey]);
}
// Update the metadata value (key to update, new value)
fileMetaData[metaDataKeyToUpdate] = metaDataNewValue;
// Update the existing S3 object
PutObjectRequest putRequest1 = new PutObjectRequest
{
BucketName = bucketName,
Key = setKeyName,
ContentBody = fileContents
};
// Set the metadata
foreach (string metadataKey in response.Metadata.Keys)
{
putRequest1.Metadata.Add(metadataKey, fileMetaData[metadataKey]);
}
PutObjectResponse response1 = await s3Client.PutObjectAsync(putRequest1);