亚马逊 S3 列出“目录”

2022-09-01 10:46:26

我已通过 AWS S3 管理控制台在 S3 中创建了一个层次结构。如果我运行以下代码来列出存储桶:

AmazonS3 s3 = new AmazonS3Client(CRED);
ListObjectsRequest lor = new ListObjectsRequest()
                             .withBucketName("myBucket")
                             .withPrefix("code/");
ObjectListing objectListing = s3.listObjects(lor);
for (S3ObjectSummary summary: objectListing.getObjectSummaries()) {
    System.out.println(summary.getKey());
}

我得到:

code/ 
code/03000000-0001-0000-0000-000000000000/ 
code/03000000-0001-0000-0000-000000000000/special.js 
code/03000000-0001-0000-0000-000000000000/test.js 
code/03000000-0002-0000-0000-000000000000/ 

这正是我所期望的。如果我添加一个分隔符,以便我只在“code/”下直接列出内容,我现在不会得到任何子“目录”。

将上面的行(在末尾添加与Delimiter())更改为:

ListObjectsRequest lor = new ListObjectsRequest().withBucketName("myBucket")
                                                 .withPrefix("code/")
                                                 .withDelimiter("/");

我现在只得到:

code/ 

我知道S3没有“目录”,而是分隔键,但这种行为似乎很奇怪?我如何列出仅紧挨着“代码”的内容?


答案 1

如果您的密钥没有内容,S3 会将其视为“通用前缀”:

http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/model/ObjectListing.html#getCommonPrefixes%28%29

public List getCommonPrefixes()

获取此对象列表中包含的常见前缀。仅当在原始请求中指定了分隔符时,才会存在公共前缀。

每个公共前缀表示 S3 存储桶中的一组键,这些键已在对象摘要结果中压缩并省略。这允许应用程序按层次结构组织和浏览其密钥,类似于文件系统将文件组织到目录中的方式。

例如,考虑一个包含以下键的存储桶:

“foo/bar/baz”
“foo/bar/bash”
“foo/bar/bang”
“foo/boo”

如果在此存储桶上调用前缀为“foo/”且分隔符=“/”的 listObjects,则返回的 S3ObjectListing 将在公共前缀列表 (“foo/bar/”) 中包含一个条目,并且以该公共前缀开头的键都不会包含在对象摘要列表中。

返回:此对象列表中包含的常见前缀列表,如果未找到常见前缀,则可能是空列表。


答案 2

您可以指定列出存储桶的任何目录层次结构。当前缀设置为“”或“/”时,表示存储桶的第一级目录。设置特定子目录时,将显示子目录的键列表。

参考Charles Menguy在“Amazon S3列出”目录“中的答案,并添加了一些修改。

  public List<String> listKeysInBucket(String bucketName, String prefix) {
    Boolean isTopLevel = false;
    String delimiter = "/";
    if(prefix == "" || prefix == "/") {
      isTopLevel = true;
    }
    if (!prefix.endsWith(delimiter)) {
      prefix += delimiter;
    }

    ListObjectsRequest listObjectsRequest = null;
    if (isTopLevel) {
      listObjectsRequest =
          new ListObjectsRequest().withBucketName(bucketName).withDelimiter(delimiter);
    } else {
      listObjectsRequest = new ListObjectsRequest().withBucketName(bucketName).withPrefix(prefix)
          .withDelimiter(delimiter);
    }
    ObjectListing objects = s3Client.listObjects(listObjectsRequest);
    return objects.getCommonPrefixes();
  }

推荐