Как обновить метаданные для существующего файла Amazon S3?
Мне нужно обновить заголовок управления кэшем во всех облачных файлах AmazonS3. Однако я не могу понять, как это сделать, используя API jclouds.
Я использую плагин apache jclouds. И у меня есть два ответных ответа:
Первый ответ предполагает использовать класс SwiftKey Api, который недоступен в плагине grails jcloud. Второй ответ - использование AWS java sdk, для которого уже существует плагин wraps grails https://grails.org/plugin/aws-sdk, но он не поддерживает обновление метаданных.
Ответы
Ответ 1
Можно изменить метаданные, выполнив копию объекта (см. Как обновить метаданные с помощью 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);
Независимо от того, философски ли это "обновление", вам решать.
Ответ 2
Вы не можете:
Каждый объект Amazon S3 имеет данные, ключ и метаданные. Ключ объекта (или имя ключа) однозначно идентифицирует объект в ведре. Метаданные объекта представляет собой набор пар имя-значение. Вы можете установить метаданные объекта в это время вы его загрузите. После загрузки объекта вы не можете изменять объект метаданные. Единственный способ изменить метаданные объекта - сделать копию объект и установить метаданные.
http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html
Ответ 3
Пример PHP
Я понимаю, что этот вопрос не был специфичным для PHP, но он может кому-то помочь, так как это лучший результат в Google.
Это перезапишет существующий объект.
$client = new \Aws\S3\S3Client([
'version' => '2006-03-01',
'region' => 'BUCKET-REGION'
]);
$updateResponse = $client->copyObject([
'Key' => 'OBJECTKEY',
'Bucket' => 'MYBUCKET',
'CopySource' => 'MYBUCKET/OBJECTKEY',
'MetadataDirective' => 'REPLACE',
'Metadata' => [
'width' => 441,
'height' => 189
]
]);
![The Content Type was an existing metadata item]()
Ответ 4
По состоянию на март 2018 года изменилась последняя версия AWS SDK для .NET Core. Теперь он использует асинхронное программирование. Многие из сигнатур метода изменились. Хотя вы по-прежнему не можете изменять метаданные без решения по копированию объектов, предложенного Дэном, код для этого имеет.
Мое решение - обновить существующий объект 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);