2

So I want to delete all the objects that could be inside a folder in s3 (basically with a certain prefix).
How do I do that? I am currently using this while (true) loop, but I am told it is not a good approach to use while (true).
This is what I am using right now.

while (true) {
    for (S3ObjectSummary objectSummary: objectListing.getObjectSummaries()) {
        this.s3Client.deleteObject(bucketName, objectSummary.getKey());
    }

    if (objectListing.isTruncated()) {
        objectListing = s3Client.listNextBatchOfObjects(objectListing);
    } else {
        break;
    }
}
HoRn
  • 1,458
  • 5
  • 20
  • 25
  • In [this related question](https://stackoverflow.com/q/8027265/12567365), as well as the `while (listing.isTruncated())` approach in the accepted answer, see also the updated approaches in this [newer answer](https://stackoverflow.com/a/53825029/12567365). – andrewJames Oct 04 '22 at 13:41
  • You might also look at deleteObjects, which can delete a batch of objects. – jarmod Oct 04 '22 at 14:16
  • tell me if i am correct ? isTruncuated is only required when partial response is sent , that is if there are more than 1000 objects right? but if i can be assured , that in my base prefix there wont be more than 20-30 objects can i simply remove the while loop? and just delete the all object listing i get in a single call? @andrewJames . – Inderjeet Chawla Oct 04 '22 at 14:51
  • main issue is about checking for isTruncuated() in the while loop. @jarmod. – Inderjeet Chawla Oct 04 '22 at 14:52
  • 1
    "_tell me if i am correct_" - I think you should be able to test that for yourself. Also, did you look at the examples in the newer answer, which do not require paging? – andrewJames Oct 04 '22 at 15:06
  • Just write code for the general case, assuming you might get a truncated set of results. It's not much more difficult to do it right. You can still use the batch deleteObjects, even if the listing is paginated - simply accumulate the complete list of objects and then batch them for deletion. Or investigate calling batch deleteObjects for each possibly-truncated set of results from the listing. – jarmod Oct 04 '22 at 15:09
  • so i guess i need to have a loop anyways , to check for truncuated part. wrote for the general case. – Inderjeet Chawla Oct 05 '22 at 03:39

1 Answers1

2

When using the AWS SDK for Java V2 S3 Client, you can set up your code to use a List of ObjectIdentifier objects to delete. Add a new entry to the List for each object to delete. Specify the path where the object is located in the ObjectIdentifier key value. This is where you specify the path in a bucket where the object is located.

You need to populate the LIST with the number of objects that you want to delete. So if you have 20 objects - then you need to add 20 entries to the List each with a valid key value that references the object to delete.

Then call deleteObjects(). This is a cleaner way to delete many objects. That is, you can delete multiple objects in 1 call vs many calls.

See this code.

 public static void deleteBucketObjects(S3Client s3, String bucketName, String objectName) {

        ArrayList<ObjectIdentifier> toDelete = new ArrayList<>();
        toDelete.add(ObjectIdentifier.builder()
            .key(objectName)
            .build());

        try {
            DeleteObjectsRequest dor = DeleteObjectsRequest.builder()
                .bucket(bucketName)
                .delete(Delete.builder()
                .objects(toDelete).build())
                .build();
            
            s3.deleteObjects(dor);

        } catch (S3Exception e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
        
        System.out.println("Done!");
    }
smac2020
  • 9,637
  • 4
  • 24
  • 38
  • No I think you misunderstood the question , i have a requirement of deleting objects in a folder , i wrote multiple objects , cause they are not actually folder but same prefixes . i wanted to know if there was a way to delete multiple objects , without checking for truncuated listing using loops. i guess there are none . so i have gone with the same approach i mentioned above. – Inderjeet Chawla Oct 05 '22 at 03:41
  • "deleting objects in a folder" - this is exactly what the above code shows. However - you specify the path where the object is located in the ObjectIdentifier key value. This logic deletes multiple objects in 1 service call vs looping and making many service calls that deletes an object 1 at a time. In the above code, you need to populate the LIST with the number of objects that you want to delete. So if you have 20 objects - then you need to add 20 entries to the List each with a valid key value, – smac2020 Oct 05 '22 at 13:56
  • but how do i get those n number of objects based on a folder name? for that i will have to loop and check until isTruncuated() method returns falls ? am i right or am i not able to understand the solution you are proposing ? – Inderjeet Chawla Oct 06 '22 at 06:40
  • If you have objects in a bucket location named foo/foo2, you call ListObjects https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javav2/example_code/s3/src/main/java/com/example/s3/ListObjects.java. Then you get the keys at that bucket location and populate the ArrayList toDelete List object and call s3.deleteObjects(dor). – smac2020 Oct 06 '22 at 12:46