web-dev-qa-db-ja.com

「ディレクトリ」をリストするAmazon S3

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には「ディレクトリ」ではなく、区切られたキーがありますが、この動作は奇妙に思えますか? 「コード」のすぐ下にあるものをどのようにリストしますか?

23
Kong

コンテンツがないキーがある場合、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つのエントリが含まれ、それで始まるキーは含まれません。共通のプレフィックスは、オブジェクトの要約リストに含まれます。

戻り値:このオブジェクトリストに含まれる共通プレフィックスのリスト。共通プレフィックスが見つからなかった場合、空のリストになる場合があります。

28
Kong

バケットをリストするディレクトリ階層を指定できます。プレフィックスが「」または「/」に設定されている場合、バケットの第1レベルのディレクトリを示します。特定のサブディレクトリを設定すると、サブディレクトリのキーのリストが表示されます。

「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();
  }
1
Elon