2012-03-30 74 views
7

我试图确定一个文件夹是否存在于我的Amazon S3存储桶中,并且它不是我想要创建的。Amazon S3通过.NET SDK创建文件夹vs通过管理控制台

此刻,我可以使用.NET SDK创建如下文件夹:

 public void CreateFolder(string bucketName, string folderName) 
    { 
     var folderKey = folderName + "/"; //end the folder name with "/" 

     var request = new PutObjectRequest(); 

     request.WithBucketName(bucketName); 

     request.StorageClass = S3StorageClass.Standard; 
     request.ServerSideEncryptionMethod = ServerSideEncryptionMethod.None; 

     //request.CannedACL = S3CannedACL.BucketOwnerFullControl; 

     request.WithKey(folderKey); 

     request.WithContentBody(string.Empty); 

     S3Response response = m_S3Client.PutObject(request); 

    } 

现在,当我尝试看看是否存在该文件夹使用此代码:

 public bool DoesFolderExist(string key, string bucketName) 
    { 
     try 
     { 
      S3Response response = m_S3Client.GetObjectMetadata(new GetObjectMetadataRequest() 
       .WithBucketName(bucketName) 
       .WithKey(key)); 

      return true; 
     } 
     catch (Amazon.S3.AmazonS3Exception ex) 
     { 
      if (ex.StatusCode == System.Net.HttpStatusCode.NotFound) 
       return false; 

      //status wasn't not found, so throw the exception 
      throw; 
     } 
    } 

这不可能找到该文件夹​​。奇怪的是,如果我使用AWS管理控制台创建文件夹,'DoesFolderExist'方法可以看到它。

我不确定它是一个ACL/IAM的东西,但不知道如何解决这个问题。

回答

10

你的代码实际上适用于我,但有几件事你需要注意。

据我所知,Amazon S3没有文件夹的概念,但单个客户端可能会像显示S3对象一样显示文件夹。所以如果你创建一个名为A/B的对象,那么客户端可能会显示它,就好像它是一个名为B的对象,它位于名为A的文件夹内。这很直观,似乎已经成为标准,但是不会显示模拟空文件夹有一个标准。

例如,我用你的方法创建一个名为Test的文件夹,然后最终创建一个名为Test /的对象。但我在AWS Explorer中创建了名为Test2的文件夹(即Visual Studio的插件),并最终创建了一个名为Test2/Test2_ $文件夹的对象$ (AWS Explorer将同时显示Test和Test2作为文件夹)

Once这意味着你不需要需要来创建“文件夹”,然后才能使用它,这可能意味着你不需要一个DoesFolderExist方法。

正如我提到我想你的代码,它的工作原理,并发现它创建的测试文件夹,但关键不得不进行调整以找到AWS资源管理器中创建的文件夹,即

DoesFolderExist("Test/"    , bucketName); // Returns true 
DoesFolderExist("Test2/"    , bucketName); // Returns false 
DoesFolderExist("Test2/Test2_$folder$", bucketName); // Returns true 

所以,如果你这样做还是希望有一个DoesFolderExist方法,那么它可能会更安全,只是寻找一个与文件夹名称+“/”开头的任何对象,即像

ListObjectsRequest request = new ListObjectsRequest(); 
request.BucketName = bucketName ; 
request.WithPrefix(folderName + "/"); 
request.MaxKeys = 1; 

using (ListObjectsResponse response = m_S3Client.ListObjects(request)) 
{ 
    return (response.S3Objects.Count > 0); 
} 
+0

有用的信息 - 谢谢 – 2013-07-24 08:45:48

0
 ListObjectsRequest findFolderRequest = new ListObjectsRequest(); 
     findFolderRequest.BucketName = bucketName; 
     findFolderRequest.Prefix = path; 
     ListObjectsResponse findFolderResponse = s3Client.ListObjects(findFolderRequest); 
     Boolean folderExists = findFolderResponse.S3Objects.Any(); 

路径可以是像“图像/ 40 /”。 使用上面的代码可以检查桶中是否存在所谓的“images/40 /”文件夹。

但是Amazon S3数据模型没有文件夹的概念。当您尝试将图像或文件复制到特定路径时,如果此共存文件夹不存在,它将作为此文件或图像的密钥名称的一部分自动创建。因此,您实际上不需要检查该文件夹是否存在。

来自docs.aws.amazon.com的非常重要的信息:Amazon S3数据模型是一个扁平结构:您创建一个存储桶并且该存储桶存储对象。没有子包或子文件夹的层次结构;但是,您可以使用密钥名称前缀和分隔符来推断逻辑层次结构,如Amazon S3控制台所做的那样。

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