web-dev-qa-db-fra.com

Comment répertorier tous les objets AWS S3 dans un compartiment à l'aide de Java

Quelle est la manière la plus simple d'obtenir une liste de tous les éléments d'un compartiment S3 à l'aide de Java?

List<S3ObjectSummary> s3objects = s3.listObjects(bucketName,prefix).getObjectSummaries();

Cet exemple ne renvoie que 1000 éléments.

54
Ron D.

Ce pourrait être une solution de contournement, mais cela a résolu mon problème:

ObjectListing listing = s3.listObjects( bucketName, prefix );
List<S3ObjectSummary> summaries = listing.getObjectSummaries();

while (listing.isTruncated()) {
   listing = s3.listNextBatchOfObjects (listing);
   summaries.addAll (listing.getObjectSummaries());
}
90
Ron D.

Ceci provient directement de la documentation AWS:

AmazonS3 s3client = new AmazonS3Client(new ProfileCredentialsProvider());        

ListObjectsRequest listObjectsRequest = new ListObjectsRequest()
    .withBucketName(bucketName)
    .withPrefix("m");
ObjectListing objectListing;

do {
        objectListing = s3client.listObjects(listObjectsRequest);
        for (S3ObjectSummary objectSummary : 
            objectListing.getObjectSummaries()) {
            System.out.println( " - " + objectSummary.getKey() + "  " +
                    "(size = " + objectSummary.getSize() + 
                    ")");
        }
        listObjectsRequest.setMarker(objectListing.getNextMarker());
} while (objectListing.isTruncated());
17
user3652779

Je traite une grande collection d'objets générés par notre système; nous avons changé le format des données stockées et avons dû vérifier chaque fichier, déterminer lesquels étaient dans l'ancien format et les convertir. Il existe d'autres façons de procéder, mais celle-ci se rapporte à votre question.

    ObjectListing list = amazonS3Client.listObjects(contentBucketName, contentKeyPrefix);

    do {                

        List<S3ObjectSummary> summaries = list.getObjectSummaries();

        for (S3ObjectSummary summary : summaries) {

            String summaryKey = summary.getKey();               

            /* Retrieve object */

            /* Process it */

        }

        list = amazonS3Client.listNextBatchOfObjects(list);

    }while (list.isTruncated());
10
Alberto A. Medina

Pour ceux qui lisent ceci en 2018+. Deux nouvelles API sans pagination sont disponibles: une dans AWS SDK pour Java 1.x et une autre dans 2.x.

1 fois

Il y a nouvelle API dans Java SDK qui vous permet de parcourir les objets dans le bucket S3 sans traiter la pagination:

AmazonS3 s3 = AmazonS3ClientBuilder.standard().build();

S3Objects.inBucket(s3, "the-bucket").forEach((S3ObjectSummary objectSummary) -> {
    // TODO: Consume `objectSummary` the way you need
    System.out.println(objectSummary.key);
});

Cette itération est paresseuse:

La liste des S3ObjectSummary s sera récupérée paresseusement, une page à la fois, selon les besoins. La taille de la page peut être contrôlée avec la méthode withBatchSize(int) .

2.x

L'API a changé, voici donc une version du SDK 2.x:

S3Client client = S3Client.builder().region(Region.US_EAST_1).build();
ListObjectsV2Request request = ListObjectsV2Request.builder().bucket("the-bucket").prefix("the-prefix").build();
ListObjectsV2Iterable response = client.listObjectsV2Paginator(request);

for (ListObjectsV2Response page : response) {
    page.contents().forEach((S3Object object) -> {
        // TODO: Consume `object` the way you need
        System.out.println(object.key());
    });
}

ListObjectsV2Iterable est aussi paresseux:

Lorsque l'opération est appelée, une instance de cette classe est renvoyée. À ce stade, aucun appel de service n'est encore effectué et il n'y a donc aucune garantie que la demande est valide. Au fur et à mesure que vous parcourez l'itérable, le SDK commence à charger paresseusement les pages de réponse en effectuant des appels de service jusqu'à ce qu'il ne reste plus de pages ou que votre itération s'arrête. S'il y a des erreurs dans votre demande, vous ne verrez les échecs qu'après avoir commencé l'itération à travers l'itérable.

7
madhead

Liste des clés à l'aide du kit AWS SDK pour Java

http://docs.aws.Amazon.com/AmazonS3/latest/dev/ListingObjectKeysUsingJava.html

import Java.io.IOException;
import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.ListObjectsRequest;
import com.amazonaws.services.s3.model.ListObjectsV2Request;
import com.amazonaws.services.s3.model.ListObjectsV2Result;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.s3.model.S3ObjectSummary;

public class ListKeys {
    private static String bucketName = "***bucket name***";

    public static void main(String[] args) throws IOException {
        AmazonS3 s3client = new AmazonS3Client(new ProfileCredentialsProvider());
        try {
            System.out.println("Listing objects");
            final ListObjectsV2Request req = new ListObjectsV2Request().withBucketName(bucketName);
            ListObjectsV2Result result;
            do {               
               result = s3client.listObjectsV2(req);

               for (S3ObjectSummary objectSummary : 
                   result.getObjectSummaries()) {
                   System.out.println(" - " + objectSummary.getKey() + "  " +
                           "(size = " + objectSummary.getSize() + 
                           ")");
               }
               System.out.println("Next Continuation Token : " + result.getNextContinuationToken());
               req.setContinuationToken(result.getNextContinuationToken());
            } while(result.isTruncated() == true ); 

         } catch (AmazonServiceException ase) {
            System.out.println("Caught an AmazonServiceException, " +
                    "which means your request made it " +
                    "to Amazon S3, but was rejected with an error response " +
                    "for some reason.");
            System.out.println("Error Message:    " + ase.getMessage());
            System.out.println("HTTP Status Code: " + ase.getStatusCode());
            System.out.println("AWS Error Code:   " + ase.getErrorCode());
            System.out.println("Error Type:       " + ase.getErrorType());
            System.out.println("Request ID:       " + ase.getRequestId());
        } catch (AmazonClientException ace) {
            System.out.println("Caught an AmazonClientException, " +
                    "which means the client encountered " +
                    "an internal error while trying to communicate" +
                    " with S3, " +
                    "such as not being able to access the network.");
            System.out.println("Error Message: " + ace.getMessage());
        }
    }
}
7
Anton Bondarenko

Comme une solution légèrement plus concise pour répertorier les objets S3 lorsqu'ils peuvent être tronqués:

ListObjectsRequest request = new ListObjectsRequest().withBucketName(bucketName);
ObjectListing listing = null;

while((listing == null) || (request.getMarker() != null)) {
  listing = s3Client.listObjects(request);
  // do stuff with listing
  request.setMarker(listing.getNextMarker());
}
7
pedorro

Gray, ta solution était étrange mais tu sembles être un gars sympa.

AmazonS3Client s3Client = new AmazonS3Client(new BasicAWSCredentials( ....

ObjectListing images = s3Client.listObjects(bucketName); 

List<S3ObjectSummary> list = images.getObjectSummaries();
for(S3ObjectSummary image: list) {
    S3Object obj = s3Client.getObject(bucketName, image.getKey());
    writeToFile(obj.getObjectContent());
}
4
jon

Je sais que c'est un vieux post, mais cela pourrait encore être utile à n'importe qui: Le SDK Java/Android sur la version 2.1 fournit une méthode appelée setMaxKeys. Comme ça:

s3objects.setMaxKeys(arg0)

Vous avez probablement déjà trouvé une solution, mais veuillez cocher une réponse comme étant correcte afin qu'elle puisse aider d'autres à l'avenir.

3
Vini.g.fer

Cela a fonctionné pour moi.

Thread thread = new Thread(new Runnable(){
    @Override
    public void run() {
        try {
            List<String> listing = getObjectNamesForBucket(bucket, s3Client);
            Log.e(TAG, "listing "+ listing);

        }
        catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, "Exception found while listing "+ e);
        }
    }
});

thread.start();



  private List<String> getObjectNamesForBucket(String bucket, AmazonS3 s3Client) {
        ObjectListing objects=s3Client.listObjects(bucket);
        List<String> objectNames=new ArrayList<String>(objects.getObjectSummaries().size());
        Iterator<S3ObjectSummary> oIter=objects.getObjectSummaries().iterator();
        while (oIter.hasNext()) {
            objectNames.add(oIter.next().getKey());
        }
        while (objects.isTruncated()) {
            objects=s3Client.listNextBatchOfObjects(objects);
            oIter=objects.getObjectSummaries().iterator();
            while (oIter.hasNext()) {
                objectNames.add(oIter.next().getKey());
            }
        }
        return objectNames;
}
3
user2798227