Determine if an object exists in a S3 bucket based on wildcard

Can someone please show me how to determine if a certain file/object exists in a S3 bucket and display a message if it exists or if it does not exist.

Basically I want it to:

1) Check a bucket on my S3 account such as testbucket

2) Inside of that bucket, look to see if there is a file with the prefix test_ (test_file.txt or test_data.txt).

3) If that file exists, then display a MessageBox (or Console message) that the file exists, or that the file does not exist.

Can someone please show me how to do this?


Solution 1:

Using the AWSSDK For .Net I Currently do something along the lines of:

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

It kinda sucks, but it works for now.

Solution 2:

Use the S3FileInfo.Exists method:

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

Solution 3:

This solves it:

List the bucket for existing objects and use a prefix like so.

    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
    }

Solution 4:

I know this question is a few years old but the new SDK handles this beautifully. If anyone is still searching this. You are looking for S3DirectoryInfo Class

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

Solution 5:

Not sure if this applies to .NET Framework, but the .NET Core version of AWS SDK (v3) only supports async requests, so I had to use a slightly different solution:

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

And, if you want to search a folder:

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

Usage:

var testExists = await FileExists("testBucket", "test_");
// or...
var testExistsInFolder = await FileExists("testBucket", "testFolder/testSubFolder", "test_");