【问题标题】:Amazon S3 listing "directories"Amazon S3 列出“目录”
【发布时间】:2013-07-07 20:08:31
【问题描述】:

我通过 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/”下直接列出内容,我现在不会得到任何子“目录”。

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

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

而我现在只得到:

code/ 

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

【问题讨论】:

  • 你试过withPrefix("code")(省略斜线)
  • 是的,这让我一无所获。根据 AWS doco,您需要将尾随分隔符附加到前缀。

标签: java amazon-web-services amazon-s3


【解决方案1】:

如果您有没有内容的键,S3 将它们视为“通用前缀”:

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

公共列表 getCommonPrefixes()

获取包含在此对象列表中的公共前缀。常见的 只有在原始文件中指定了分隔符时才会出现前缀 请求。

每个公共前缀代表 S3 存储桶中的一组键,它们具有 已从对象摘要结果中压缩和省略。这 允许应用程序分层组织和浏览其密钥, 类似于文件系统如何将文件组织到目录中。

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

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

如果使用前缀="foo/" 和分隔符="/" 调用listObjects 此存储桶,返回的 S3ObjectListing 将包含一个条目 通用前缀列表 ("foo/bar/") 并且没有任何键开始 具有该公共前缀的将包含在对象摘要列表中。

返回:此对象列表中包含的公共前缀列表, 如果没有找到公共前缀,这可能是一个空列表。

【讨论】:

【解决方案2】:

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

参考Charles Menguy's answer in '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();
  }

【讨论】:

    【解决方案3】:
    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();
        }
    

    【讨论】:

      猜你喜欢
      • 2010-11-17
      • 1970-01-01
      • 2018-03-15
      • 2014-04-05
      • 2012-09-13
      • 2020-09-13
      • 2014-08-31
      • 2017-10-27
      • 1970-01-01
      相关资源
      最近更新 更多