1

I am using .Net Core along with Amazon's .net sdk to push and pull things from S3. I am using a folder structure in S3 that involves inserting an empty directory with several sub directories.

At a later time I insert files into those directories and move them around. Now I need to be able to remove the directory entirely.

I am able to delete all of the contents of the directory by using

await client.DeleteObjectAsync(bucketName, keyName, null).ConfigureAwait(false);

where I loop through all the files I want to delete in the given bucket. However, it always leaves me with the empty folder structure, in S3 I see that it has a content of 0 Bytes but I don't want to have to sort through thousands of empty folders to find the ones that actually have data.

Is there any way to remove an empty folder from S3 using AWS .NET SDK?

Update:

I am able to delete everything in the folder I want except for the folder itself.

using (IAmazonS3 client = new AmazonS3Client(awsCreds, Amazon.RegionEndpoint.USEast1))
            {
                try
                {
                    DeleteObjectsRequest deleteRequest = new DeleteObjectsRequest();
                    ListObjectsRequest listRequest = new ListObjectsRequest
                    {
                        BucketName = bucketName,
                        Prefix = prefix,
                        //Marker = prefix,
                    };

                    ListObjectsResponse response = await client.ListObjectsAsync(listRequest).ConfigureAwait(false);
                    // Process response
                    foreach (S3Object entry in response.S3Objects)
                    {
                        deleteRequest.AddKey(entry.Key);
                    }

                    deleteRequest.BucketName = bucketName;
                    var response2 = await client.DeleteObjectsAsync(deleteRequest).ConfigureAwait(false);

                    return true;
                }
                catch (AmazonS3Exception amazonS3Exception)
                {
                    if (amazonS3Exception.ErrorCode != null
                        && (amazonS3Exception.ErrorCode.Equals("InvalidAccessKeyId", StringComparison.Ordinal)
                        || amazonS3Exception.ErrorCode.Equals("InvalidSecurity", StringComparison.Ordinal)))
                    {
                        logger.LogError("AwsS3Service.DeleteFileFromBucket Error - Check the provided AWS Credentials.");
                    }
                    else
                    {
                        logger.LogError($"AwsS3Service.DeleteFileFromBucket Error - Message: {amazonS3Exception.Message}");
                    }
                }
            }

This deletes the entire contents of the directory I choose along with all sub directories. But the main directory remains, is there any way to remove that main directory.

A. Hasemeyer
  • 1,452
  • 1
  • 18
  • 47
  • I would question whether you actually need folders in the first place. That said, to delete a folder, simply delete the object with the key: folder/subfolder/ – jarmod Mar 26 '19 at 18:29
  • I use the folder structure because I have several tasks and just want a visual structure. But the `ListObjectResponse` seems to only let me look up by prefix, if I leave off the prefix it will return a max of 1000 keys. But the key I want isn't in that list. And just trying to delete it with the key "folder" doesn't delete the outer most folder even if it has no subfolders. – A. Hasemeyer Mar 26 '19 at 19:24
  • Related: https://stackoverflow.com/questions/19459893/how-to-create-folder-or-key-on-s3-using-aws-sdk-for-node-js/31728298#31728298 – jarmod Mar 26 '19 at 21:03

1 Answers1

0

Your code is 99% of the way there. The only thing you need to do is add the prefix variable to your keys to be deleted as well. Technically, it is a 0-byte object that needs to be 'deleted' as well.

For example, after your loop through all the objects in the response, go ahead and add the prefix variable that was added to find all those things.

foreach (S3Object entry in response.S3Objects)
{
    deleteRequest.AddKey(entry.Key);
}

// Add the folder itself to be deleted as well
deleteRequest.AddKey(prefix);
TrialAndError
  • 1,784
  • 3
  • 20
  • 41
  • Thanks but still no luck. It still leaves the first level directory, its really not that big of a deal since it is 0 bytes so it won't charge me. Just would like it to look cleaner. My folder name is a GUID, b86f4b7c-fbd4-44df-8f6d-c5fa107014c9 for example, I passed "b86f4b7c-fbd4-44df-8f6d-c5fa107014c9" and "b86f4b7c-fbd4-44df-8f6d-c5fa107014c9/" as a key and it still remained. – A. Hasemeyer Mar 28 '19 at 13:45
  • That is interesting. I took your code, started a new project and ran it with my addition and it worked as expected. I did have to click the 'refresh' button in AWS itself, as refreshing the page in browser still showed it. If you are passing in the exact key that was used to find all the sub-directories and files it should be removed. In your response from the Delete call, is there anything in `response2.DeleteErrors`? – TrialAndError Mar 28 '19 at 19:04
  • Did you delete all of the sub-folders in one request then in another request delete the main folder? Or was it all in one call? – A. Hasemeyer Mar 29 '19 at 13:27