AmazonS3通过.NET SDK创建文件夹与通过管理控制台创建文件夹

本文关键字:创建 文件夹 管理 管理控制 控制台 SDK 通过 AmazonS3 NET | 更新日期: 2023-09-27 18:29:42

我正在尝试确定我的Amazon S3 Bucket上是否存在文件夹,如果不存在,我想创建它。

目前,我可以使用.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的问题,但不确定如何解决。

AmazonS3通过.NET SDK创建文件夹与通过管理控制台创建文件夹

您的代码实际上对我有效,但您需要注意一些事情。

据我所知,AmazonS3没有文件夹的概念,但单个客户端可能会像显示S3对象一样显示S3对象。因此,如果您创建了一个名为A/B的对象,那么客户端可能会将其显示为名为A的文件夹中的一个名称为B的对象。这是直观的,似乎已经成为一种标准,但模拟一个空文件夹似乎没有标准。

例如,我使用您的方法创建了一个名为Test的文件夹,然后实际创建了一种名为Test/的对象。但我在AWS Explorer中创建了一个名为Test2的文件夹(即Visual Studio的插件),它最终创建了一种名为Test2/Test2_$folder$的对象(AWS Explorer将Test和Test2显示为文件夹)

这意味着,在使用"文件夹"之前,您不需要创建"文件夹",这可能意味着您不需要DoesFolderExist方法。

正如我所提到的,我尝试了你的代码,它工作并找到了它创建的测试文件夹,但必须调整密钥才能找到AWS Explorer创建的文件夹,即

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

因此,如果你仍然想有一个DoesFolderExist方法,那么只查找任何以folderName+"/"开头的对象可能会更安全,比如

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

刚刚用AWS.Net SDK:版本2将上述代码重构为异步方法

public async Task CreateFoldersAsync(string bucketName, string path)
    {
        path = path.EnsureEndsWith('/');
        IAmazonS3 client =
            new AmazonS3Client(YOUR.AccessKeyId, YOUR.SecretAccessKey,
            RegionEndpoint.EUWest1);
        var findFolderRequest = new ListObjectsV2Request();
        findFolderRequest.BucketName = bucketName;
        findFolderRequest.Prefix = path;
        findFolderRequest.MaxKeys = 1;
        ListObjectsV2Response findFolderResponse = 
           await client.ListObjectsV2Async(findFolderRequest);

        if (findFolderResponse.S3Objects.Any())
        {
            return;
        }
        
        PutObjectRequest request = new PutObjectRequest()
        {
            BucketName = bucketName,
            StorageClass = S3StorageClass.Standard,
            ServerSideEncryptionMethod = ServerSideEncryptionMethod.None,
            Key = path, 
            ContentBody = string.Empty
        };
        // add try catch in case you have exceptions shield/handling here 
        PutObjectResponse response = await client.PutObjectAsync(request);
    }
        ListObjectsRequest findFolderRequest = new ListObjectsRequest();
        findFolderRequest.BucketName = bucketName;
        findFolderRequest.Prefix = path;
        ListObjectsResponse findFolderResponse = s3Client.ListObjects(findFolderRequest);
        Boolean folderExists = findFolderResponse.S3Objects.Any();

路径可以类似于"images/40/"。使用以上代码可以检查bucket下是否存在所谓的文件夹"images/40/"。

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

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

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