what's best way to check if a S3 object exists?

Viewed 19214

Currently, I make a GetObjectMetaDataRequest, if the GetObjectMetaDataResponse throw an exception means the object doesn't exist. Is there a better way to check whether the file exists without downloading the file.

7 Answers

If you are in a similar situation as myself and are using .Net Core and don't have access to Amazon.S3.IO (and S3FileInfo method), you can do the following using asynchronous GetObjectMetadataRequest method:

static private AmazonS3Client s3Client = new AmazonS3Client();

public static async Task<bool> FileExistsS3Async(string _bucket, string _key)
{
      GetObjectMetadataRequest request = new GetObjectMetadataRequest()
      {
            BucketName = _bucket,
            Key = _key
      };

      try
      {
            await s3Client.GetObjectMetadataAsync(request);
            return true;
      }
      catch (AmazonS3Exception exception)
      {
            return false;
      }
}

This function has worked for me when calling within a Unity game. You can also call the above function synchronously using the following:

bool exists = Task.Run(()=>FileExistsS3Async(_bucket, _key)).Result;

You can use this code to check whether an object exist in S3 or not:

public class S3CheckFileExists
{
    private readonly IAmazonS3 amazonS3;

    public S3CheckFileExists(IAmazonS3 amazonS3)
    {
        this.amazonS3 = amazonS3;
    }

    public async Task<bool> S3ObjectExists(string bucketName, string keyLocation)
    {
        var listS3Objects = await this.amazonS3.ListObjectsV2Async(new ListObjectsV2Request
        {
            BucketName = bucketName,
            Prefix = keyLocation, // eg myfolder/myimage.jpg (no / at start)
            MaxKeys = 1
        });

        if (listS3Objects.S3Objects.Any() == false || listS3Objects.S3Objects.All(x => x.Key != keyLocation))
        {
            // S3 object doesn't exist
            return false;
        }

        // S3 object exists
        return true;
    }
}

You'll need to register IAmazonS3 in your IoC (aka services) container though:

services.AddAWSService<IAmazonS3>();
Related