Amazon S3:如何获取存储桶中的文件夹列表?

时间:2015-11-05 12:52:43

标签: c# amazon-web-services amazon-s3 aws-sdk

我发现的一切,就是这种方法GET Bucket 但我无法理解如何才能获得当前文件夹中的文件夹列表。我需要使用哪个前缀和分隔符?这有可能吗?

5 个答案:

答案 0 :(得分:19)

为了举例,假设我在名为USEast1的{​​{1}}区域中有一个存储桶,其中包含以下键:

MyBucketName

使用文件夹可能会造成混淆,因为S3本身不支持层次结构 - 相反,这些只是像任何其他S3对象一样的键。文件夹只是S3 Web控制台中的一个抽象,可以更轻松地导航存储桶。因此,当我们以编程方式工作时,我们希望找到与“文件夹”(分隔符'/',size = 0)相匹配的键,因为它们可能是S3控制台提供给我们的'文件夹'。

请注意以下两个示例:我使用的是AWSSDK.S3版本3.1 NuGet包。

示例1:存储桶中的所有文件夹

此代码在S3文档中从this basic example进行了修改,以列出存储桶中的所有密钥。下面的示例将标识以分隔符 temp/ temp/foobar.txt temp/txt/ temp/txt/test1.txt temp/txt/test2.txt temp2/ 结尾的所有键,并且也是空的。

/

预期输出到控制台:

IAmazonS3 client;
using (client = new AmazonS3Client(Amazon.RegionEndpoint.USEast1))
{
    // Build your request to list objects in the bucket
    ListObjectsRequest request = new ListObjectsRequest
    {
        BucketName = "MyBucketName"
    };

    do
    {
        // Build your call out to S3 and store the response
        ListObjectsResponse response = client.ListObjects(request);

        // Filter through the response to find keys that:
        // - end with the delimiter character '/' 
        // - are empty. 
        IEnumerable<S3Object> folders = response.S3Objects.Where(x =>
            x.Key.EndsWith(@"/") && x.Size == 0);

        // Do something with your output keys.  For this example, we write to the console.
        folders.ToList().ForEach(x => System.Console.WriteLine(x.Key));

        // If the response is truncated, we'll make another request 
        // and pull the next batch of keys
        if (response.IsTruncated)
        {
            request.Marker = response.NextMarker;
        }
        else
        {
            request = null;
        }
    } while (request != null);
}

示例2:匹配指定前缀的文件夹

您可以进一步将此限制为仅通过在ListObjectsRequest上设置temp/ temp/txt/ temp2/ 属性来检索与指定Prefix匹配的文件夹。

Prefix

当应用于示例1时,我们期望以下输出:

ListObjectsRequest request = new ListObjectsRequest
    {
        BucketName = "MyBucketName",
        Prefix = "temp/"
    };

进一步阅读:

答案 1 :(得分:4)

另一种更简单的方法是使用https://github.com/minio/minio-dotnet

Minio .Net实现了最小的API,可与Amazon S3和其他兼容的存储解决方案配合使用。

以下示例显示了如何仅筛选出目录。这里,CommonPrefix通过ListObjects()API抽象为文件夹。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Minio;
using Minio.Xml;

namespace Minio.Examples
{
    class ListObjects
    {
        static int Main(string[] args)
        {
            var client = new MinioClient("https://s3.amazonaws.com", "ACCESSKEY", "SECRETKEY");

            var items = client.ListObjects("bucket");

            foreach (Item item in items)
            {
                if (item.IsDir)
                {
                    Console.Out.WriteLine("{0}", item.Key);
                }
            }
            return 0;
        }
    }
}

答案 2 :(得分:3)

使用prefix the/path/to/read/(注意没有前导斜杠,但 是一个尾部斜杠),{{1 } delimiter,您将在/内找到该文件夹​​中的所有文件夹。

  

CommonPrefixes

     

只有在指定分隔符时,响应才能包含<CommonPrefixes>。执行此操作时,CommonPrefixes包含Prefix与分隔符指定的下一次出现的字符串之间的所有键(如果有)。实际上,CommonPrefixes列出了与CommonPrefixes指定的目录中的子目录相同的键。例如,如果前缀是notes /并且分隔符是斜杠(/),则在notes / summer / july中,公共前缀是notes / summer /。在计算返回数时,在公共前缀中汇总的所有密钥都计为单个返回。见MaxKeys。

     

http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGET.html

答案 3 :(得分:3)

安东尼在这里缺少的是文件夹不一定有与之关联的密钥。如果在S3中创建了一个文件,并给出了一个像“folder / name.ext”这样的键,S3将显示一个“文件夹”文件夹,但它没有一个键,这意味着你没有在结果中得到它。

捕获这些文件夹的唯一方法是查看密钥本身,并使用正则表达式为“/”字符的密钥名称。如果我知道C#好一点,我会给你写一个代码示例,但是我在另一个问题上写了python example作为参考。

答案 4 :(得分:-1)

在参数中添加定界符“ /”对我来说很有效。

万一有人需要NodeJS解决方案,这就是我所使用的:

listdelim: function (path) {
    const params = {
        Bucket: process.env['bucket'],
        MaxKeys: 1000,
        Prefix: path,
        Delimiter: '/'
    }
    return new Promise((resolve, reject) => {
        s3.listObjectsV2(params, function (err, data) {
            if (err) {
                console.log(err, err.stack)
                reject(err)
            } else {
                resolve(data)
            }
        })
    })
}