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é.
En utilisant l'outil officiel aws-sdk :
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
Edition 2017 : Même 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();
});
}
const { S3 } = require("aws-sdk");
const s3 = new S3();
async function* listAllKeys(opts) {
opts = { ...opts };
do {
const data = await s3.listObjectsV2(opts).promise();
opts.ContinuationToken = data.NextContinuationToken;
yield data;
} while (opts.ContinuationToken);
}
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'
};
async function main() {
// using for of await loop
for await (const data of listAllKeys(opts)) {
console.log(data.Contents);
}
}
main();
C'est tout.
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();
const lister = (opts) => (o$) => {
let needMore = true;
const process = async () => {
for await (const data of listAllKeys(opts)) {
o$.next(data);
if (!needMore) break;
}
o$.complete();
};
process();
return () => (needMore = false);
};
// 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();
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),
});
import {
paginateListObjectsV2,
S3Client,
S3ClientConfig,
} from "@aws-sdk/client-s3";
/* // For Deno
import {
paginateListObjectsV2,
S3Client,
S3ClientConfig,
} from "https://deno.land/x/aws_sdk@v3.14.0.0/client-s3/mod.ts"; */
const s3Config: S3ClientConfig = {
credentials: {
accessKeyId: "accessKeyId",
secretAccessKey: "secretAccessKey",
},
region: "us-east-1",
};
const client = new S3Client(s3Config);
const s3Opts = { Bucket: "bucket-xyz" };
async function getAllS3Files() {
const totalFiles = [];
for await (const data of paginateListObjectsV2({ client }, s3Opts)) {
totalFiles.push(...(data.Contents ?? []));
}
return totalFiles;
}
Voici le code Node que j'ai écrit pour assembler les objets S3 à partir de listes tronquées.
var params = {
Bucket: <yourbucket>,
Prefix: <yourprefix>,
};
var s3DataContents = []; // Single array of all combined S3 data.Contents
function s3Print() {
if (program.al) {
// --al: Print all objects
console.log(JSON.stringify(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 à de listObject la documentation de NextMarker, qui est PAS toujours présent dans l'objet de données retourné, donc je ne l'utilise pas du tout dans le code ci-dessus ...
NextMarker - (Chaîne) Quand la réponse est tronquée (le IsTruncated dans la réponse est vrai), vous pouvez utiliser le nom de la clé dans la fonction ce champ comme marqueur dans la requête suivante pour obtenir le prochain ensemble d'objets. Amazon S3 liste les objets par ordre alphabétique. est renvoyé uniquement si vous avez spécifié le paramètre de requête delimiter est spécifié. Si la réponse n'inclut pas le NextMarker et qu'il est tronquée, vous pouvez utiliser la valeur de la dernière Clé dans la réponse comme comme marqueur dans la requête suivante pour obtenir le prochain ensemble de clés .
L'ensemble du programme a été repoussé à https://github.com/kenklin/s3list .
En effet aws2js prend en charge l'énumération des objets d'un seau à un niveau bas via s3.get()
appel de méthode. Pour ce faire, il faut passer prefix
qui est documenté sur Page 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);
});
El data
dans le snippet ci-dessus contient une liste de tous les objets dans le fichier bucketName
seau.
Publié sur copie knox quand je ne trouvais pas de bonne solution existante. Enveloppe tous les détails de pagination de l'API Rest dans un flux de nœuds familier :
var knoxCopy = require('knox-copy');
var client = knoxCopy.createClient({
key: '<api-key-here>',
secret: '<secret-here>',
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 suffira :
client.listPageOfKeys({
prefix: 'smaller/bucket/o/fun'
}, function(err, page) {
console.log(page.Contents); // <- Here's your list of files
});
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.
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.