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 对象需要包含BucketKey,你不能保留PrefixgetObject 将出错。 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 个月以前的文件列表

如何使用 Java 列出存储桶中的所有 AWS S3 对象

我只想提取 Aws s3 存储桶名称并以列表的形式显示

将对象上传到 S3 存储桶时如何触发 AWS Cloudformation 堆栈的更新?

使用 Boto3 如何从 AWS s3 下载文件列表作为 zip 文件维护文件夹结构?

如何从 S3 加载泡菜文件以在 AWS Lambda 中使用?