根据通配符确定S3存储桶中是否存在对象

fra*_*Xis 38 c# amazon-s3

有人可以告诉我如何确定S3存储桶中是否存在某个文件/对象,并显示消息是否存在或是否存在.

基本上我想要它:

1)检查我的S3帐户上的一个桶,例如testbucket

2)在该存储桶内部,查看是否存在前缀为test_(test_file.txt或test_data.txt)的文件.

3)如果该文件存在,则显示该文件存在的MessageBox(或控制台消息),或该文件不存在.

有人可以告诉我该怎么做吗?

Pra*_*eep 59

使用S3FileInfo.Exists方法:

using (var client = Amazon.AWSClientFactory.CreateAmazonS3Client(accessKey, secretKey))
{
    S3FileInfo s3FileInfo = new Amazon.S3.IO.S3FileInfo(client, "your-bucket-name", "your-file-name");
    if (s3FileInfo.Exists)
    {
         // file exists
    }
    else
    {
        // file does not exist
    }   
}
Run Code Online (Sandbox Code Playgroud)

  • 如果key不存在,则抛出AmazonS3Exception异常,并显示消息'Forbidden 403'.非常愚蠢的东西......但如果我们确信我们可以访问存储桶,我们可以将其视为"错误". (3认同)
  • @PavelShkleinik - github 上可用的源代码是最近的:https://github.com/aws/aws-sdk-net/blob/master/AWSSDK_DotNet35/Amazon.S3/IO/S3FileInfo.cs - 我相信你说的是幸运的是,情况不再如此。 (2认同)
  • 我知道这是一个旧答案,请注意此解决方案基于异常,它使用 GetObjectMetadata 如果文件不存在则抛出异常 https://github.com/aws/aws-sdk-net/blob /6c3be79bdafd5bfff1ab0bf5fec17abc66c7b516/sdk/src/Services/S3/Custom/_bcl/IO/S3FileInfo.cs#L118 (2认同)

Ale*_*lex 51

使用AWSSDK For .Net I目前做的事情如下:

public bool Exists(string fileKey, string bucketName)
{
        try
        {
            response = _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;
        }
}
Run Code Online (Sandbox Code Playgroud)

它有点糟糕,但它现在有效.

  • 这个答案来自2010年 - SDK现在支持Exists - http://docs.amazonwebservices.com/sdkfornet/latest/apidocs/html/T_Amazon_S3_IO_S3FileInfo.htm (18认同)
  • 改为抛出(ex)到普通投掷. (3认同)
  • 这里有几个问题.首先,该技术不支持基于公共前缀匹配对象.其次,一个相当常见的执行路径(该文件不存在)将导致抛出异常 - 这会影响性能. (3认同)
  • 我不明白这如何回答使用通配符的问题。如何检查是否存在具有相同前缀的文件? (2认同)

Alv*_*vis 12

这解决了它:

列出现有对象的存储桶,并使用这样的前缀.

    var request = new ListObjectsRequest()
        .WithBucketName(_bucketName)
        .WithPrefix(keyPrefix);

    var response = _amazonS3Client.ListObjects(request);

    var exists = response.S3Objects.Count > 0;

    foreach (var obj in response.S3Objects) {
        // act
    }
Run Code Online (Sandbox Code Playgroud)


Rob*_*iha 11

我知道这个问题已经有几年了,但是新的SDK处理得很漂亮.如果有人还在搜索这个.您正在寻找S3DirectoryInfo

using (IAmazonS3 s3Client = new AmazonS3Client(accessKey, secretKey))
{
    S3DirectoryInfo s3DirectoryInfo = new Amazon.S3.IO.S3DirectoryInfo(s3Client, "testbucket");
    if (s3DirectoryInfo.GetFiles("test*").Any())
    {
        //file exists -- do something
    }
    else
    {
        //file doesn't exist -- do something else
    }
}
Run Code Online (Sandbox Code Playgroud)


2To*_*oad 7

不确定这是否适用于 .NET Framework,但 AWS SDK (v3) 的 .NET Core 版本仅支持异步请求,因此我不得不使用稍微不同的解决方案:

/// <summary>
/// Determines whether a file exists within the specified bucket
/// </summary>
/// <param name="bucket">The name of the bucket to search</param>
/// <param name="filePrefix">Match files that begin with this prefix</param>
/// <returns>True if the file exists</returns>
public async Task<bool> FileExists(string bucket, string filePrefix)
{
    // Set this to your S3 region (of course)
    var region = Amazon.RegionEndpoint.USEast1;

    using (var client = new AmazonS3Client(region))
    {
        var request = new ListObjectsRequest {
            BucketName = bucket,
            Prefix = filePrefix,
            MaxKeys = 1
        };

        var response = await client.ListObjectsAsync(request, CancellationToken.None);

        return response.S3Objects.Any();
    }
}
Run Code Online (Sandbox Code Playgroud)

而且,如果要搜索文件夹:

/// <summary>
/// Determines whether a file exists within the specified folder
/// </summary>
/// <param name="bucket">The name of the bucket to search</param>
/// <param name="folder">The name of the folder to search</param>
/// <param name="filePrefix">Match files that begin with this prefix</param>
/// <returns>True if the file exists</returns>
public async Task<bool> FileExists(string bucket, string folder, string filePrefix)
{
    return await FileExists(bucket, $"{folder}/{filePrefix}");
}
Run Code Online (Sandbox Code Playgroud)

用法:

var testExists = await FileExists("testBucket", "test_");
// or...
var testExistsInFolder = await FileExists("testBucket", "testFolder/testSubFolder", "test_");
Run Code Online (Sandbox Code Playgroud)