Node.js & Amazon S3: comment parcourir tous les fichiers d’un compartiment?

Existe-t-il une bibliothèque client Amazon S3 pour Node.js qui permet de répertorier tous les fichiers dans le compartiment S3?

Les aws2js et knox les plus connus ne semblent pas avoir cette fonctionnalité.

En utilisant le aws-sdk officiel:

var allKeys = []; function listAllKeys(marker, cb) { s3.listObjects({Bucket: s3bucket, Marker: marker}, function(err, data){ allKeys.push(data.Contents); if(data.IsTruncated) listAllKeys(data.NextMarker, cb); else cb(); }); } 

voir s3.listObjects

Edit 2017 : Idée de base, mais listObjectsV2( ... ) est maintenant recommandé et utilise un ContinuationToken (voir s3.listObjectsV2 ):

 var allKeys = []; function listAllKeys(token, cb) { var opts = { Bucket: s3bucket }; if(token) opts.ContinuationToken = token; s3.listObjectsV2(opts, function(err, data){ allKeys = allKeys.concat(data.Contents); if(data.IsTruncated) listAllKeys(data.NextContinuationToken, cb); else cb(); }); } 

Voici le code Node que j’ai écrit pour assembler les objects S3 à partir de listes tronquées.

 var params = { Bucket: , Prefix: , }; var s3DataContents = []; // Single array of all combined S3 data.Contents function s3Print() { if (program.al) { // --al: Print all objects console.log(JSON.ssortingngify(s3DataContents, null, " ")); } else { // --b: Print key only, otherwise also print index var i; for (i = 0; i < s3DataContents.length; i++) { var head = !program.b ? (i+1) + ': ' : ''; console.log(head + s3DataContents[i].Key); } } } function s3ListObjects(params, cb) { s3.listObjects(params, function(err, data) { if (err) { console.log("listS3Objects Error:", err); } else { var contents = data.Contents; s3DataContents = s3DataContents.concat(contents); if (data.IsTruncated) { // Set Marker to last returned key params.Marker = contents[contents.length-1].Key; s3ListObjects(params, cb); } else { cb(); } } }); } s3ListObjects(params, s3Print); 

Faites attention à la documentation listObject de NextMarker, qui n'est PAS toujours présente dans l'object de données renvoyé, donc je ne l'utilise pas du tout dans le code ci-dessus ...

NextMarker - (Ssortingng) Lorsque la réponse est tronquée (la valeur de l'élément IsTruncated dans la réponse est true), vous pouvez utiliser le nom de clé dans ce champ comme marqueur dans la requête suivante pour obtenir le prochain ensemble d'objects. Amazon S3 répertorie les objects dans l'ordre alphabétique Remarque: Cet élément est renvoyé uniquement si le paramètre de demande de délimiteur est spécifié. Si la réponse n'inclut pas NextMarker et qu'elle est tronquée, vous pouvez utiliser la valeur de la dernière clé dans la réponse comme marqueur dans la requête suivante pour obtenir le prochain ensemble de clés d'object .

Le programme entier a maintenant été poussé à https://github.com/kenklin/s3list .

En fait, aws2js prend en charge la liste des objects dans un s3.get() bas niveau via l’appel de la méthode s3.get() . Pour ce faire, il faut passer un paramètre de prefix documenté sur la page de l’API REST Amazon S3 :

 var s3 = require('aws2js').load('s3', awsAccessKeyId, awsSecretAccessKey); s3.setBucket(bucketName); var folder = encodeURI('some/path/to/S3/folder'); var url = '?prefix=' + folder; s3.get(url, 'xml', function (error, data) { console.log(error); console.log(data); }); 

La variable de data dans l’extrait de bucketName ci-dessus contient une liste de tous les objects du bucketName .

Knox-copy publié quand je ne pouvais pas trouver une bonne solution existante. Enveloppe tous les détails de la pagination de l’API Rest dans un stream de noeuds familier:

 var knoxCopy = require('knox-copy'); var client = knoxCopy.createClient({ key: '', secret: '', bucket: 'mrbucket' }); client.streamKeys({ // omit the prefix to list the whole bucket prefix: 'buckets/of/fun' }).on('data', function(key) { console.log(key); }); 

Si vous répertoriez moins de 1000 fichiers, une seule page fonctionnera:

 client.listPageOfKeys({ prefix: 'smaller/bucket/o/fun' }, function(err, page) { console.log(page.Contents); // <- Here's your list of files }); 

C’est une vieille question et je suppose que le SDK AWS JS a beaucoup changé depuis qu’on l’a demandé. Voici encore une autre façon de le faire ces jours-ci:

 s3.listObjects({Bucket:'mybucket', Prefix:'some-pfx'}). on('success', function handlePage(r) { //... handle page of contents r.data.Contents if(r.hasNextPage()) { // There's another page; handle it r.nextPage().on('success', handlePage).send(); } else { // Finished! } }). on('error', function(r) { // Error! }). send(); 

Meekohi a fourni une très bonne réponse, mais la (nouvelle) documentation indique que NextMarker peut être indéfini. Dans ce cas, vous devez utiliser la dernière clé comme marqueur.

Ainsi, son exemple de code peut être changé en:

var allKeys = []; function listAllKeys(marker, cb) { s3.listObjects({Bucket: s3bucket, Marker: marker}, function(err, data){ allKeys.push(data.Contents); if(data.IsTruncated) listAllKeys(data.NextMarker || data.Contents[data.Contents.length-1].Key, cb); else cb(); }); }

Impossible de commenter la réponse originale car je n’ai pas la réputation requirejse. Toutes mes excuses pour la mauvaise note btw.

Bien que la réponse de @ Meekohi fonctionne techniquement, j’ai eu assez de peine avec la partie S3 du kit SDK AWS pour NodeJS. Après toutes les difficultés rencontrées avec des modules tels que aws-sdk , s3 , knox , j’ai décidé d’installer s3cmd via le gestionnaire de paquets du système d’exploitation et de faire un shell avec child_process

Quelque chose comme:

  var s3cmd = new cmd_exec('s3cmd', ['ls', filepath, 's3://'+inputBucket], function (me, data) {me.stdout += data.toSsortingng();}, function (me) {me.exit = 1;} ); response.send(s3cmd.stdout); 

(Utilisation de l’implémentation cmd_exec de cette question )

Cette approche fonctionne très bien, y compris pour d’autres problèmes tels que le téléchargement de fichiers.

Si vous souhaitez obtenir la liste des clés uniquement dans un dossier spécifique à l’intérieur d’un compartiment S3, cela vous sera utile.

Fondamentalement, la fonction listObjects commencera à chercher à partir du Marker nous avons défini et elle recherchera jusqu’à maxKeys: 1000 comme limite. il va donc rechercher un dossier à la fois et obtenir les 1000 premières clés qu’il trouve dans un dossier différent dans un compartiment.

Considérez que j’ai beaucoup de dossiers dans mon seau avec le préfixe comme prod/some date/, Ex: prod/2017/05/12/ ,prod/2017/05/13/,etc

Je veux récupérer la liste des objects (noms de fichiers) uniquement dans le dossier prod/2017/05/12/ alors je spécifierai prod/2017/05/12/ comme mes débuts et prod/2017/05/13/ [votre prochain dossier name] comme ma fin et dans le code je brise la boucle quand je rencontre la fin.

Chaque Key de data.Contents ressemblera à ceci.

 { Key: 'prod/2017/05/13/4bf2c675-a417-4c1f-a0b4-22fc45f99207.jpg', LastModified: 2017-05-13T00:59:02.000Z, ETag: '"630b2sdfsdfs49ef392bcc16c833004f94ae850"', Size: 134236366, StorageClass: 'STANDARD', Owner: { } } 

Code:

 var list = []; function listAllKeys(s3bucket, start, end) { s3.listObjects({ Bucket: s3bucket, Marker: start, MaxKeys: 1000, }, function(err, data) { if (data.Contents) { for (var i = 0; i < data.Contents.length; i++) { var key = data.Contents[i].Key; //See above code for the structure of data.Contents if (key.substring(0, 19) != end) { list.push(key); } else { break; // break the loop if end arrived } } console.log(list); console.log('Total - ', list.length); } }); } listAllKeys('BucketName', 'prod/2017/05/12/', 'prod/2017/05/13/'); 

Sortie:

 [ 'prod/2017/05/12/05/4bf2c675-a417-4c1f-a0b4-22fc45f99207.jpg', 'prod/2017/05/12/05/a36528b9-e071-4b83-a7e6-9b32d6bce6d8.jpg', 'prod/2017/05/12/05/bc4d6d4b-4455-48b3-a548-7a714c489060.jpg', 'prod/2017/05/12/05/f4b8d599-80d0-46fa-a996-e73b8fd0cd6d.jpg', ... 689 more items ] Total - 692