AWS S3 对象列表
Posted
技术标签:
【中文标题】AWS S3 对象列表【英文标题】:AWS S3 object listing 【发布时间】:2015-08-23 22:03:31 【问题描述】:我正在通过 node.js 使用 aws-sdk。我想列出指定文件夹中的图像,例如
我想列出此位置的所有文件和文件夹,但不列出文件夹(图像)内容。 aws-sdk 中有list Object function,但它也列出了所有嵌套文件。
代码如下:
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);
);
【问题讨论】:
S3 没有文件夹/文件等的概念......它只有键 - 您可以使用键中的 / 来模仿文件夹结构。 请显示您目前拥有的代码 var AWS = require('aws-sdk'); AWS.config.update(accessKeyId: 'mykey', secretAccessKey: 'mysecret', region: 'myregion'); var s3 = 新 AWS.S3(); var params = 桶:'mystore.in',分隔符:'',前缀:'s/5469b2f5b4292d22522e84e0/ms.files'; s3.listObjects(params, function (err, data) if(err)throw err; console.log(data); ); 请编辑问题以包含(和格式化)代码 你到底想通过console.log(data)
得到什么
【参考方案1】:
现在使用此代码可以正常工作:
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);
);
【讨论】:
仅供参考 - 在listObjects
之后,我正在做getObject
,我发现params
对象需要包含Bucket
和Key
,你不能保留Prefix
或getObject
将出错。 Delimiter
也可能会导致问题,但我无法确定。干杯【参考方案2】:
文件夹是虚幻的,但 S3 确实提供了一种机制来模拟它们的存在。
如果您将Delimiter
设置为/
,那么每一层响应还将返回一个包含下一层“文件夹”的CommonPrefixes
数组,您将把它附加到此请求的前缀中,以检索下一层。
如果您的Prefix
是一个“文件夹”,则附加一个尾部斜杠。否则,您将发出不必要的请求,因为第一个请求将返回一个公共前缀。例如,文件夹“foo”将返回一个公共前缀“foo/”。
【讨论】:
如何获取最新的对象,有没有排序选项 @Johne 不幸的是,目前还没有,除非您首先获取所有对象并在您身边进行排序。即使是 AWS S3 控制台也只会在您单击表头时对客户端进行排序【参考方案3】:我贴了一点module,其中列出了你给它的“文件夹”的内容:
s3ls(bucket: 'my-bucket-name').ls('/', console.log);
将打印如下内容:
files: [ 'funny-cat-gifs-001.gif' ],
folders: [ 'folder/', 'folder2/' ]
还有那个
s3ls(bucket: 'my-bucket-name').ls('/folder', console.log);
将打印
files: [ 'folder/cv.docx' ],
folders: [ 'folder/sub-folder/' ]
UPD:最新版本支持async/await Promise接口:
const files, folders = await lister.ls("/my-folder/subfolder/");
这里是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)
;
;
【讨论】:
【参考方案4】:您可以在 s3 API 参数中使用Prefix
。我正在添加一个我在项目中使用的示例:
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));
);
)
这里Bucket
是包含文件夹的存储桶的名称,Folder
是您要在其中列出文件的文件夹的名称。
【讨论】:
你可以使用 s3.listObjects(params).promise() 来避免 Promise 样板。 @Guido 确实如此。感谢您的改进。【参考方案5】:您也可以使用minio-js 客户端库,它是开源的并且与 AWS S3 api 兼容。
您可以简单地使用list-objects.js
示例,更多文档可在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'
)
// List all object paths in bucket my-bucketname.
var objectsStream = s3Client.listObjects('my-bucketname', '', true)
objectsStream.on('data', function(obj)
console.log(obj)
)
objectsStream.on('error', function(e)
console.log(e)
)
希望对你有帮助。
免责声明:我为Minio工作
【讨论】:
var s3Client = new Minio( ^ TypeError: Minio is not a constructor
【参考方案6】:
正如 cmets 中提到的,S3 不“知道”文件夹,只知道键。您可以在键中使用 / 来模仿文件夹结构。请参阅此处了解更多信息 - http://docs.aws.amazon.com/AmazonS3/latest/UG/FolderOperations.html
也就是说,你可以将你的代码修改成这样:
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);
);
这将检查每个键是否包含 /
【讨论】:
以上是关于AWS S3 对象列表的主要内容,如果未能解决你的问题,请参考以下文章
使用“aws s3”实用程序在 S3 中获取 1 个月以前的文件列表
将对象上传到 S3 存储桶时如何触发 AWS Cloudformation 堆栈的更新?