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

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

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

  temp/ temp/foobar.txt temp/txt/ temp/txt/test1.txt temp/txt/test2.txt temp2/ 

使用文件夹可能会令人困惑,因为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 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); } 

预期输出到控制台:

 temp/ temp/txt/ temp2/ 

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

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

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

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

 temp/ temp/txt/ 

进一步阅读:

  • S3文档 – 使用文件夹
  • .NET SDK文档 – ListObjects

或者,另一种更简单的方法是使用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; } } } 

使用the/path/to/read/ prefix (注意没有前导斜杠,但有一个尾部斜杠)和/ delimiter ,你会在找到该文件夹​​中的所有文件夹。

CommonPrefixes

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

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

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

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