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

neu*_*t47 7 c# amazon-s3 amazon-web-services aws-sdk

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

Ant*_*ace 19

例如,假设我在所USEast1调用的区域中有一个桶MyBucketName,其中包含以下键:

 temp/
 temp/foobar.txt
 temp/txt/
 temp/txt/test1.txt
 temp/txt/test2.txt
 temp2/
Run Code Online (Sandbox Code Playgroud)

使用文件夹可能会令人困惑,因为S3本身不支持层次结构 - 相反,这些只是像任何其他S3对象一样的键.文件夹只是S3 Web控制台中的一个抽象,可以更轻松地导航存储桶.因此,当我们以编程方式工作时,我们希望找到与"文件夹"(分隔符'/',size = 0)的尺寸匹配的密钥,因为它们可能是由S3控制台呈现给我们的"文件夹".

请注意两个示例:我正在使用AWSSDK.S3版本3.1 NuGet包.

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

此代码在S3文档中从此基本示例进行了修改,以列出存储桶中的所有密钥.下面的示例将标识以分隔符字符结尾的所有键/,并且也是空的.

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);
}
Run Code Online (Sandbox Code Playgroud)

预期输出到控制台:

temp/
temp/txt/
temp2/
Run Code Online (Sandbox Code Playgroud)

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

您可以进一步将此限制为仅Prefix通过PrefixListObjectsRequest上设置属性来检索与指定匹配的文件夹.

ListObjectsRequest request = new ListObjectsRequest
    {
        BucketName = "MyBucketName",
        Prefix = "temp/"
    };
Run Code Online (Sandbox Code Playgroud)

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

temp/
temp/txt/
Run Code Online (Sandbox Code Playgroud)

进一步阅读:

  • 如果您在此之后仍然遇到问题,可以确保您的ListObjectsRequest不会过多地限制您的请求.例如,如果您指定了前缀...在没有它的情况下测试您的代码,以确保它不会过多地限制您的请求.如果这不起作用,请随意提出一个新问题(这个问题非常明确,我们不想让它混乱),并提供一个桶结构示例和您尝试制作的请求. (2认同)

Mic*_*bot 5

使用prefixthe/path/to/read/(请注意,有没有斜线,但有尾随斜线),以及delimiter/,你会发现该文件夹内内的所有文件夹<CommonPrefixes>

通用前缀

CommonPrefixes仅当您指定分隔符时,响应才能包含。执行此操作时,CommonPrefixes将在Prefix和定界符指定的字符串的下一次出现之间包含所有(如果有)键。实际上,CommonPrefixes列出的键的作用类似于所指定目录中的子目录Prefix。例如,如果前缀为notes /,而分隔符为斜杠(/),则在notes / summer / july中,公共前缀为notes / summer /。计算返回数时,所有以公共前缀汇总的键都计为一次返回。请参见MaxKeys。

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


Har*_*ana 5

另外一种更简单的方法是使用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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Nat*_*ard 5

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

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