22

以下のコードを使用して、s3 バケットからすべてのファイル名のリストを取得しています。s3 に 2 つのバケットがあります。以下のバケットの 1 つで、コードはすべてのファイル名 (1000 を超える) を返しますが、別のバケットでは同じコードで 1000 のファイル名しか返されません。何が起こっているのかわかりません。同じコードが 1 つのバケットで実行され、他のバケットでは実行されないのはなぜですか?

また、私のバケットには階層構造の folder/filename.jpg があります。

ObjectListing objects = s3.listObjects("bucket.new.test");
do {
    for (S3ObjectSummary objectSummary : objects.getObjectSummaries()) {
        String key = objectSummary.getKey();
        System.out.println(key);
    }
    objects = s3.listNextBatchOfObjects(objects);
} while (objects.isTruncated());
4

8 に答える 8

19

@Abhishekの回答を改善しています。このコードは少し短く、変数名は固定されています。

オブジェクトのリストを取得し、その内容をコレクションに追加してから、リストからオブジェクトの次のバッチを取得する必要があります。リストが切り詰められなくなるまで操作を繰り返します。

List<S3ObjectSummary> keyList = new ArrayList<S3ObjectSummary>();
ObjectListing objects = s3.listObjects("bucket.new.test");
keyList.addAll(objects.getObjectSummaries());

while (objects.isTruncated()) {
    objects = s3.listNextBatchOfObjects(objects);
    keyList.addAll(objects.getObjectSummaries());
}
于 2015-01-13T21:28:32.770 に答える
8

Scala 開発者の場合、公式のAWS SDK for Javaを使用して、AmazonS3 バケットのコンテンツのフル スキャンとマップを実行する再帰関数です。

import com.amazonaws.services.s3.AmazonS3Client
import com.amazonaws.services.s3.model.{S3ObjectSummary, ObjectListing, GetObjectRequest}
import scala.collection.JavaConversions.{collectionAsScalaIterable => asScala}

def map[T](s3: AmazonS3Client, bucket: String, prefix: String)(f: (S3ObjectSummary) => T) = {

  def scan(acc:List[T], listing:ObjectListing): List[T] = {
    val summaries = asScala[S3ObjectSummary](listing.getObjectSummaries())
    val mapped = (for (summary <- summaries) yield f(summary)).toList

    if (!listing.isTruncated) mapped.toList
    else scan(acc ::: mapped, s3.listNextBatchOfObjects(listing))
  }

  scan(List(), s3.listObjects(bucket, prefix))
}

上記のカリーmap()化された関数を呼び出すには、作成済みの (そして適切に初期化された) AmazonS3Client オブジェクト (公式のAWS SDK for Java API リファレンスを参照)、バケット名、および最初のパラメータ リストのプレフィックス名を渡すだけです。またf()、2 番目のパラメーター リストで各オブジェクトの概要をマップするために適用する関数を渡します。

例えば

val keyOwnerTuples = map(s3, bucket, prefix)(s => (s.getKey, s.getOwner))

(key, owner)そのバケット/プレフィックス内のタプルの完全なリストを返します

また

map(s3, "bucket", "prefix")(s => println(s))

通常、関数型プログラミングでモナドによってアプローチするように

于 2014-06-05T12:20:53.640 に答える
6

上記のコードを変更して、 forループを使用してオブジェクトを 1 つずつ追加する代わりにaddAllを使用すると、うまくいきました。

List<S3ObjectSummary> keyList = new ArrayList<S3ObjectSummary>();
ObjectListing object = s3.listObjects("bucket.new.test");
keyList = object.getObjectSummaries();
object = s3.listNextBatchOfObjects(object);

while (object.isTruncated()){
  keyList.addAll(current.getObjectSummaries());
  object = s3.listNextBatchOfObjects(current);
}
keyList.addAll(object.getObjectSummaries());

その後、リストkeyListに対して任意のイテレータを使用できます。

于 2012-10-25T08:07:14.703 に答える
2

すべてのオブジェクト(1000を超えるキー)を取得する場合は、最後のキーを含む別のパケットをS3に送信する必要があります。これがコードです。

private static String lastKey = "";
private static String preLastKey = "";
...

do{
        preLastKey = lastKey;
        AmazonS3 s3 = new AmazonS3Client(new ClasspathPropertiesFileCredentialsProvider());

        String bucketName = "bucketname";           

        ListObjectsRequest lstRQ = new ListObjectsRequest().withBucketName(bucketName).withPrefix("");  

        lstRQ.setMarker(lastKey);  

        ObjectListing objectListing = s3.listObjects(lstRQ);

        //  loop and get file on S3
        for (S3ObjectSummary objectSummary : objectListing.getObjectSummaries()) {
             //   get oject and do something.....
        }
}while(lastKey != preLastKey);
于 2013-03-12T03:21:59.910 に答える
0

デフォルトでは、API は最大 1,000 個のキー名を返します。応答に含まれるキーは少なくなる可能性がありますが、それ以上になることはありません。より良い実装は、新しい ListObjectsV2 API を使用することです。

List<S3ObjectSummary> docList=new ArrayList<>();
    ListObjectsV2Request req = new ListObjectsV2Request().withBucketName(bucketName).withPrefix(folderFullPath);
    ListObjectsV2Result listing;
    do{
        listing=this.getAmazonS3Client().listObjectsV2(req);
        docList.addAll(listing.getObjectSummaries());
        String token = listing.getNextContinuationToken();
        req.setContinuationToken(token);
        LOG.info("Next Continuation Token for listing documents is :"+token);
    }while (listing.isTruncated());
于 2020-07-14T06:08:13.710 に答える