2015-09-18 15 views
10

Potrzebuję zaktualizować nagłówek kontroli pamięci podręcznej we wszystkich plikach chmurowych AmazonS3. Jednak nie mogę się dowiedzieć, jak to zrobić, używając interfejsu API jclouds. Używam wtyczki apache jclouds. I mam dwa powiązane odpowiedzi:Jak zaktualizować metadane istniejącego pliku Amazon S3?

Pierwsza odpowiedź sugeruje użycie SwiftKey Api klasę, która nie jest dostępna w plugin Grails'S jcloud. Druga odpowiedź to użycie AWS java sdk, dla której istnieje już wtyczka grails, https://grails.org/plugin/aws-sdk, ale nie obsługuje ona aktualizacji metadanych.

Odpowiedz

14

Nie można:

Każdy obiekt Amazon S3 ma dane, klucz i metadanych. Klucz obiektu (lub nazwa klucza ) jednoznacznie identyfikuje obiekt w wiadrze. Metadane obiektu to zestaw par nazwa-wartość. Możesz ustawić metadane obiektu w czasie, gdy je przesyłasz. Po przesłaniu obiektu nie można modyfikować metadanych obiektu . Jedynym sposobem modyfikacji metadanych obiektu jest zrobienie kopii obiektu i ustawienie metadanych.

http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html

+1

znajdę dokumentację AWS na temat metadanych bardzo mylące - wzdłuż boku link podasz, znalazłem inny łącze do ich podręcznika użytkownika, gdzie pokazuje, jak dodawać lub usuwać metadane obiektów za pomocą konsoli zarządzania. Jedynym rozwiązaniem tego konfliktu, jaki mogę wymyślić, jest to, że kiedy mówią "nie można modyfikować metadanych obiektu", oznacza to, że nie można zmodyfikować wartości określonego klucza metadanych. jaka jest twoja myśl? http://docs.aws.amazon.com/AmazonS3/latest/UG/EditingtheMetadataofanObject.html – Israel

+0

Może to oznaczać, że nie można modyfikować metadanych za pomocą interfejsu REST, ale można za pomocą konsoli zarządzania? (Za kulisami prawdopodobnie klonowałby i usuwał). – kaifong

+0

Zobacz moje rozwiązanie poniżej, możesz zaktualizować istniejący obiekt S3 i ustawić nowe/zaktualizowane metadane w tym samym czasie. Jest podobny do rozwiązania kopiowania. – robnick

13

Jest możliwe, aby zmienić metadane, wykonując kopię obiektu (patrz 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); 

Czy jest filozoficznie "update" to do ciebie, aby zdecydować, .

+1

Dzięki Dan, kończę robić to samo. –

0

Od marca 2018 r. Zmieniono najnowszą wersję pakietu SDK AWS dla .NET Core. Teraz używa programowania asynchronicznego. Wiele sygnatur metody uległo zmianie. Chociaż nadal nie można zmienić metadanych bez rozwiązania kopiowania obiektów, które zasugerował Dan, kod do tego jest taki.

Moim rozwiązaniem jest aktualizacja istniejącego obiektu S3 za pomocą zmodyfikowanych metadanych.

Poniższe działa dla mnie, aby zaktualizować jedną wartość metadanych (na podstawie klucza i nowej wartości). Mam dwie pętle do ustawiania metadane, ale może to być zoptymalizowane, aby tylko jedno:

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);