Node.js & Amazon S3: How to iterate through all files in a bucket?

前端 未结 15 971
情书的邮戳
情书的邮戳 2020-12-02 14:17

Is there any Amazon S3 client library for Node.js that allows listing of all files in S3 bucket?

The most known aws2js and knox don\'t seem to have this functionalit

15条回答
  •  北海茫月
    2020-12-02 14:48

    Using Async Generator

    Import S3

    const { S3 } = require("aws-sdk");
    const s3 = new S3();
    

    create a generator function to retrieve all the files list

    async function* listAllKeys(opts) {
      opts = { ...opts };
      do {
        const data = await s3.listObjectsV2(opts).promise();
        opts.ContinuationToken = data.NextContinuationToken;
        yield data;
      } while (opts.ContinuationToken);
    }
    

    Prepare aws parameter, based on api docs

    const opts = {
      Bucket: "bucket-xyz" /* required */,
      // ContinuationToken: 'STRING_VALUE',
      // Delimiter: 'STRING_VALUE',
      // EncodingType: url,
      // FetchOwner: true || false,
      // MaxKeys: 'NUMBER_VALUE',
      // Prefix: 'STRING_VALUE',
      // RequestPayer: requester,
      // StartAfter: 'STRING_VALUE'
    };
    

    Use generator

    async function main() {
      // using for of await loop
      for await (const data of listAllKeys(opts)) {
        console.log(data.Contents);
      }
    }
    main();
    

    thats it

    Or Lazy Load

    async function main() {
      const keys = listAllKeys(opts);
      console.log(await keys.next());
      // {value: {…}, done: false}
      console.log(await keys.next());
      // {value: {…}, done: false}
      console.log(await keys.next());
      // {value: undefined, done: true}
    }
    main();
    

    Or Use generator to make Observable function

    const lister = (opts) => (o) => {
      let needMore = true;
      (async () => {
        const keys = listAllKeys(opts);
        for await (const data of keys) {
          o.next(data);
          if (!needMore) break;
        }
        o.complete();
      })();
      return () => (needMore = false);
    };
    

    use this observable function with RXJS

    // Using Rxjs
    
    const { Observable } = require("rxjs");
    const { flatMap } = require("rxjs/operators");
    
    function listAll() {
      return Observable.create(lister(opts))
        .pipe(flatMap((v) => v.Contents))
        .subscribe(console.log);
    }
    
    listAll();
    

    or use this observable function with Nodejs EventEmitter

    const EventEmitter = require("events");
    
    const _eve = new EventEmitter();
    
    async function onData(data) {
      // will be called for each set of data
      console.log(data);
    }
    async function onError(error) {
      // will be called if any error
      console.log(error);
    }
    async function onComplete() {
      // will be called when data completely received
    }
    _eve.on("next", onData);
    _eve.on("error", onError);
    _eve.on("complete", onComplete);
    
    const stop = lister(opts)({
      next: (v) => _eve.emit("next", v),
      error: (e) => _eve.emit("error", e),
      complete: (v) => _eve.emit("complete", v),
    });
    

提交回复
热议问题