亚马逊s3只为一个存储桶返回1000个条目,而为另一个存储桶返回所有条目(使用java sdk)?

Abh*_*hek 14 java amazon-s3

我使用下面提到的代码来获取s3存储桶中所有文件名的列表.s3中有两个桶.对于下面的一个桶代码返回所有文件名(超过1000),但相同的代码仅返回另一个桶的1000个文件名.我只是不知道发生了什么.为什么同一代码运行一个桶而不是其他?

我的桶也有层次结构文件夹/ 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());
Run Code Online (Sandbox Code Playgroud)

ofe*_*rei 12

改善@ 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());
}
Run Code Online (Sandbox Code Playgroud)

  • 我对 s3 java API 的“旧”版本也有同样的问题。亚马逊推出了“v2”,应该可以解决该问题:http://docs.aws.amazon.com/AmazonS3/latest/dev/ListingObjectKeysUsingJava.html 注意,它使用 `s3client.listObjectsV2` 和 `req.setContinuationToken(result. getNextContinuationToken())`。最后一个应该对 s3 进行单独的底层 REST GET 调用(默认情况下单个 get 返回最多 1000 个键,http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGET.html) (2认同)

Pao*_*tti 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))
}
Run Code Online (Sandbox Code Playgroud)

要调用上面的curried map()函数,只需在第一个参数列表中传递已构造的(并且已正确初始化的)AmazonS3Client对象(请参阅官方AWS SDK for Java API Reference),存储桶名称和前缀名称.同时传递f()要应用的函数以映射第二个参数列表中的每个对象摘要.

例如

val keyOwnerTuples = map(s3, bucket, prefix)(s => (s.getKey, s.getOwner))
Run Code Online (Sandbox Code Playgroud)

将返回该(key, owner)存储桶/前缀中的元组的完整列表

要么

map(s3, "bucket", "prefix")(s => println(s))
Run Code Online (Sandbox Code Playgroud)

正如Monads在函数式编程中通常所采用的那样


Abh*_*hek 6

我刚刚更改了上面的代码,使用addAll而不是使用for循环逐个添加对象,它对我有用:

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());
Run Code Online (Sandbox Code Playgroud)

之后,您可以简单地使用列表keyList上的任何迭代器.