我正在尝试确定我的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,但我不确定如何解决这个问题。
答案 0 :(得分:12)
您的代码实际上适用于我,但您需要注意一些事项。
据我了解,Amazon S3没有文件夹的概念,但个别客户端可能会像显示S3对象一样显示它们。因此,如果您创建一个名为A / B的对象,那么客户端可能会将其显示为在名为A的文件夹中的名为B的对象。这是直观的,似乎已成为标准,但模拟空文件夹不会出现有标准。
例如,我使用您的方法创建一个名为Test的文件夹,然后实际上最终创建一个名为Test /的对象。但是我在AWS Explorer中创建了一个名为Test2的文件夹(即Visual Studio的插件),最后创建了一个名为Test2 / Test2_ $ folder $的对象。 (AWS Explorer将显示Test和Test2作为文件夹)
这意味着,在你可以使用它之前,你没有需要来创建'文件夹',这可能意味着你不需要一个DoesFolderExist方法。
正如我所提到的,我尝试了你的代码并且它可以工作并找到它创建的Test文件夹,但必须调整密钥才能找到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);
}
答案 1 :(得分:0)
ListObjectsRequest findFolderRequest = new ListObjectsRequest();
findFolderRequest.BucketName = bucketName;
findFolderRequest.Prefix = path;
ListObjectsResponse findFolderResponse = s3Client.ListObjects(findFolderRequest);
Boolean folderExists = findFolderResponse.S3Objects.Any();
路径可以是" images / 40 /"。 使用上面的代码可以检查一个所谓的文件夹" images / 40 /"存在与否存在。
但亚马逊S3数据模型没有文件夹的概念。当您尝试将图像或文件复制到某个路径时,如果此共同调用的文件夹不存在,它将自动创建为此文件或图像的键名称的一部分。因此,您实际上不需要检查此文件夹是否存在。
来自docs.aws.amazon.com的非常重要的信息:Amazon S3数据模型是一种扁平结构:您创建一个存储桶,而存储桶存储对象。没有subbuckets或子文件夹的层次结构;但是,您可以使用密钥名称前缀和分隔符来推断逻辑层次结构,如Amazon S3控制台所做的那样。
http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html
答案 2 :(得分: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;
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);
}