J'utilise aws-sdk en utilisant node.js. Je souhaite répertorier les images dans le dossier spécifié, par exemple.
Je souhaite répertorier tous les fichiers et dossiers à cet emplacement, mais pas le contenu du dossier (images). Il y a fonction list Object dans aws-sdk mais il répertorie également tous les fichiers imbriqués.
Voici le code:
var AWS = require('aws-sdk');
AWS.config.update({accessKeyId: 'mykey', secretAccessKey: 'mysecret', region: 'myregion'});
var s3 = new AWS.S3();
var params = {
Bucket: 'mystore.in',
Delimiter: '',
Prefix: 's/5469b2f5b4292d22522e84e0/ms.files'
}
s3.listObjects(params, function (err, data) {
if(err)throw err;
console.log(data);
});
Les dossiers sont illusoires, mais S3 ne fournit un mécanisme pour imiter leur existence.
Si vous définissez Delimiter
sur /
puis chaque niveau de réponses renverra également un tableau CommonPrefixes
du prochain niveau de "dossiers", que vous ajouterez au préfixe de cette demande, afin de récupérer le prochain niveau.
Si votre Prefix
est un "dossier", ajoutez une barre oblique finale. Sinon, vous ferez une requête inutile, car la première requête renverra un préfixe commun. Par exemple, le dossier "foo" renverra un préfixe commun "foo /".
Cela fonctionne bien maintenant en utilisant ce code:
var AWS = require('aws-sdk');
AWS.config.update({accessKeyId: 'mykey', secretAccessKey: 'mysecret', region: 'myregion'});
var s3 = new AWS.S3();
var params = {
Bucket: 'mystore.in',
Delimiter: '/',
Prefix: 's/5469b2f5b4292d22522e84e0/ms.files/'
}
s3.listObjects(params, function (err, data) {
if(err)throw err;
console.log(data);
});
Je mets un peu module qui répertorie le contenu d'un "dossier" que vous lui donnez:
s3ls({bucket: 'my-bucket-name'}).ls('/', console.log);
imprimera quelque chose comme ceci:
{ files: [ 'funny-cat-gifs-001.gif' ],
folders: [ 'folder/', 'folder2/' ] }
Et cela
s3ls({bucket: 'my-bucket-name'}).ls('/folder', console.log);
imprimera
{ files: [ 'folder/cv.docx' ],
folders: [ 'folder/sub-folder/' ] }
Et voici le s3ls.js
:
var _ = require('lodash');
var S3 = require('aws-sdk').S3;
module.exports = function (options) {
var bucket = options.bucket;
var s3 = new S3({apiVersion: '2006-03-01'});
return {
ls: function ls(path, callback) {
var prefix = _.trimStart(_.trimEnd(path, '/') + '/', '/');
var result = { files: [], folders: [] };
function s3ListCallback(error, data) {
if (error) return callback(error);
result.files = result.files.concat(_.map(data.Contents, 'Key'));
result.folders = result.folders.concat(_.map(data.CommonPrefixes, 'Prefix'));
if (data.IsTruncated) {
s3.listObjectsV2({
Bucket: bucket,
MaxKeys: 2147483647, // Maximum allowed by S3 API
Delimiter: '/',
Prefix: prefix,
ContinuationToken: data.NextContinuationToken
}, s3ListCallback)
} else {
callback(null, result);
}
}
s3.listObjectsV2({
Bucket: bucket,
MaxKeys: 2147483647, // Maximum allowed by S3 API
Delimiter: '/',
Prefix: prefix,
StartAfter: prefix // removes the folder name from the file listing
}, s3ListCallback)
}
};
};
Vous pouvez utiliser le Prefix
dans les paramètres de l'API s3. J'ajoute un exemple que j'ai utilisé dans un projet:
listBucketContent: ({ Bucket, Folder }) => new Promise((resolve, reject) => {
const params = { Bucket, Prefix: `${Folder}/` };
s3.listObjects(params, (err, objects) => {
if (err) {
reject(ERROR({ message: 'Error finding the bucket content', error: err }));
} else {
resolve(SUCCESS_DATA(objects));
}
});
})
Ici Bucket
est le nom du compartiment qui contient un dossier et Folder
est le nom du dossier dans lequel vous souhaitez répertorier les fichiers.
Comme mentionné dans les commentaires, S3 ne "connaît" pas les dossiers, mais seulement les clés. Vous pouvez imiter une structure de dossiers avec/dans les clés. Voir ici pour plus d'informations - http://docs.aws.Amazon.com/AmazonS3/latest/UG/FolderOperations.html
Cela dit, vous pouvez modifier votre code pour obtenir quelque chose comme ceci:
s3.listObjects(params, function (err, data) {
if(err) throw
//data.contents is an array of objects according to the s3 docs
//iterate over it and see if the key contains a / - if not, it's a file (not a folder)
var itemsThatAreNotFolders = data.contents.map(function(content){
if(content.key.indexOf('/')<0) //if / is not in the key
return content;
});
console.log(itemsThatAreNotFolders);
});
Cela vérifiera chaque clé pour voir si elle contient un /
Vous pouvez également utiliser la bibliothèque client minio-js , son source ouverte et sa compatibilité avec l'API S3 de AWS.
Vous pouvez simplement utiliser list-objects.js
_ exemple, une documentation supplémentaire est disponible à l’adresse suivante: https://docs.minio.io/docs/javascript-client-api-reference .
var Minio = require ('minio') var s3Client = new Minio ({ endPoint: 's3.amazonaws.com', accessKey: 'YOUR-ACCESSKEYID', secretKey: 'YOUR-SECRETACCESSKEY' }) // Répertorie tous les chemins d'objet dans le seau my-bucketname. var objectsStream = s3Client.listObjects ('my-bucketname', '', true) objectsStream.on ('data', fonction (obj) { console.log (obj) }) objectsStream.on ('erreur', fonction (e) { console.log (e) })
J'espère que ça aide.
Disclaimer: Je travaille pour Minio