2015-09-18 60 views
10

我需要更新所有AmazonS3雲文件中的緩存控制標頭。但是,我無法弄清楚我是如何使用jclouds API來做到的。 我使用的是Apache jclouds插件。我有兩個相關的答案:如何更新現有Amazon S3文件的元數據?

第一個答案是建議使用SwiftKey API類這不是Grails中的jcloud插件可用。第二個答案是使用AWS java sdk,它已經有一個grails包裝插件https://grails.org/plugin/aws-sdk,但它不支持元數據更新。

回答

14

您不能:

每個Amazon S3的對象有數據,一鍵,和元數據。對象密鑰(或密鑰名稱)唯一標識存儲桶中的對象。對象元數據 是一組名稱 - 值對。您可以在上傳時設置對象元數據 。 上傳對象後,無法修改對象 元數據。修改對象元數據的唯一方法是製作一個對象 的副本並設置元數據。

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

+1

我找到了元數據的話題非常令人困惑的AWS文檔 - 沿邊鏈接您提供,我發現了另一個鏈接到他們的用戶指南,其中顯示瞭如何使用管理控制檯添加或刪除對象元數據。 唯一的解決這個矛盾,我可以想出,是當他們說:「你不能修改對象元數據」,他們的意思是,你不能修改特定的元數據項的值。你的想法是什麼? http://docs.aws.amazon.com/AmazonS3/latest/UG/EditingtheMetadataofanObject.html – Israel

+0

或許他們的意思是你無法通過REST接口修改元數據,但你可以通過管理控制檯? (在幕後它可能會克隆和刪除)。 – kaifong

+0

見下面我的解決方案,您可以更新現有的S3對象,並在同一時間設置新的/更新的元數據。它與複製解決方案類似。 – robnick

13

有可能通過執行對象複製更改元數據(見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

謝謝丹,我最終做了同樣的事情。 –

0

截至2018年3月,AWS SDK for .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);