64 votes

Node.js & Amazon S3 : Comment itérer à travers tous les fichiers dans un seau ?

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

Les plus connus aws2js y knox ne semblent pas disposer de cette fonctionnalité.

0 votes

Je demanderais à l'auteur s'il peut l'implémenter dans aws2js. Je pense que ce serait très facile à faire et il a été récemment actif dans le projet. Ou, si vous en êtes capable, mettez-le en œuvre vous-même.

0 votes

Vous pouvez également mettre en œuvre cette demande spécifique par le biais de leur API REST jusqu'à ce qu'il y ait un soutien dans l'une des bibliothèques.

4voto

Thijs Lowette Points 41

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

Donc 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();
  });
}

Je ne peux pas commenter la réponse originale car je n'ai pas la réputation requise. Toutes mes excuses pour le mauvais balisage.

4voto

John Tng Points 31

J'utilise cette version avec async/await .
Cette fonction renvoie le contenu dans un tableau.
J'utilise également le NextContinuationToken au lieu du marqueur.

async function getFilesRecursivelySub(param) {

    // Call the function to get list of items from S3.
    let result = await s3.listObjectsV2(param).promise();

    if(!result.IsTruncated) {
        // Recursive terminating condition.
        return result.Contents;
    } else {
        // Recurse it if results are truncated.
        param.ContinuationToken = result.NextContinuationToken;
        return result.Contents.concat(await getFilesRecursivelySub(param));
    }
}

async function getFilesRecursively() {

    let param = {
        Bucket: 'YOUR_BUCKET_NAME'
        // Can add more parameters here.
    };

    return await getFilesRecursivelySub(param);
}

2voto

logidelic Points 852

Il s'agit d'une vieille question et je suppose que le SDK AWS JS a beaucoup changé depuis qu'elle a été posée. Voici une autre façon de procéder de nos jours :

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();

1voto

Prasanth Jaya Points 1839

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

En gros, listObjects commencera la recherche à partir de l'adresse Marker que nous avons défini et il cherchera jusqu'à ce que maxKeys: 1000 comme limite. Ainsi, il cherchera un par un les dossiers et vous obtiendra les 1000 premières clés qu'il trouvera dans les différents dossiers d'un seau.

Considérons que j'ai plusieurs dossiers dans mon seau avec le préfixe suivant prod/some date/, Ex: prod/2017/05/12/ ,prod/2017/05/13/,etc .

Je veux récupérer une liste d'objets (noms de fichiers) uniquement à l'intérieur d'un fichier. prod/2017/05/12/ alors je vais spécifier prod/2017/05/12/ comme point de départ et prod/2017/05/13/ [votre nom de dossier suivant] comme fin et dans le code, je casse la boucle quand je rencontre la fin.

Chaque Key sur 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

1voto

Carlos Rodriguez Points 229

J'ai fini par construire une fonction enveloppante autour de ListObjectsV2, qui fonctionne de la même manière et prend les mêmes paramètres, mais fonctionne de manière récursive jusqu'à ce que IsTruncated=false et renvoie toutes les clés trouvées sous forme de tableau dans le second paramètre de la fonction de rappel.

const AWS = require('aws-sdk')
const s3 = new AWS.S3()

function listAllKeys(params, cb)
{
   var keys = []
   if(params.data){
      keys = keys.concat(params.data)
   }
   delete params['data']

   s3.listObjectsV2(params, function(err, data){
     if(err){
       cb(err)
     } else if (data.IsTruncated) {
       params['ContinuationToken'] = data.NextContinuationToken
       params['data'] = data.Contents
       listAllKeys(params, cb)
     } else {
       keys = keys.concat(data.Contents)
       cb(null,keys)
     }
   })
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X