亚马逊S3列出“目录”

34

我在AWS 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/”下直接的内容,则现在不会返回任何子“目录”。

将上面的行更改(在结尾处添加withDelimiter()):

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

现在我只得到:

code/ 

我知道S3没有"目录",而是使用分隔符键,但这种行为似乎很奇怪?如果我想列出仅在"code"下面的内容,应该怎么做?


你尝试过使用 withPrefix("code") 吗?(省略斜杠) - Thilo
是的,这对我没有任何作用。根据AWS文档,您需要将尾部分隔符附加到前缀。 - Kong
1
这个答案更完整:https://dev59.com/EWUq5IYBdhLWcg3wQ-NF - samthebest
3个回答

39

当您的键没有内容时,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"

如果在此存储桶上使用prefix="foo/"和delimiter="/"调用listObjects,则返回的S3ObjectListing将包含一个常见前缀列表条目("foo/bar/"),并且不会包括以该常见前缀开头的任何键在对象摘要列表中。

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


1
它返回foo /,foo / boo,并具有公共前缀foo / bar。这正确吗? - Matt Joiner
1
这个答案中有一个例子:https://dev59.com/EWUq5IYBdhLWcg3wQ-NF - Marco Roy
这里还可以找到代码示例:https://dev59.com/9VoT5IYBdhLWcg3w6ioA#39520124 - Victor Kim
这完美地解决了我的问题。感谢您的答案! - gshauger

4
您可以指定任何列出存储桶的目录层次结构。 当前缀设置为“”或“/”时,表示存储桶的第一级目录。 当设置特定子目录时,将显示该子目录的密钥列表。
参考Charles Menguy在“Amazon S3 listing “directories””中的答案,并添加了一些修改。
  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();
  }

4
This below code worked for me to list all directories in s3.

private static String bucket_name = "";
private static String secret_key = "";
private static String access_key = "";
private static String Regions region = Regions.SELECT_REGION;

public static void main(String[] args) {
        System.out.println(listKeysInBucket(bucket_name, "/"));
    }

    public static List<String> listKeysInBucket(String bucketName, String prefix) {
        boolean isTopLevel = false;
        String delimiter = "/";
        if (prefix.equals("") || prefix.equals(delimiter)) {
            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();
    }

    public static AmazonS3 s3Client() {
        AWSCredentials s3Configs = new BasicAWSCredentials(access_key,secret_key);
        return AmazonS3ClientBuilder.standard()
                .withCredentials(new AWSStaticCredentialsProvider(s3Configs)).withRegion(region )
                .build();
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接