Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
AmazonS3只为一个bucket返回1000个条目,而为另一个bucket返回所有条目(使用JavaSDK)?_Java_Amazon S3 - Fatal编程技术网

AmazonS3只为一个bucket返回1000个条目,而为另一个bucket返回所有条目(使用JavaSDK)?

AmazonS3只为一个bucket返回1000个条目,而为另一个bucket返回所有条目(使用JavaSDK)?,java,amazon-s3,Java,Amazon S3,我使用下面提到的代码从s3 bucket获取所有文件名的列表。我在s3里有两个桶。对于下面的一个bucket,代码返回所有文件名(超过1000个),但对于另一个bucket,同一代码只返回1000个文件名。我只是不明白发生了什么。 为什么一个bucket运行相同的代码而另一个bucket不运行相同的代码 我的bucket还有层次结构folder/filename.jpg ObjectListing objects = s3.listObjects("bucket.new.test"); do {

我使用下面提到的代码从s3 bucket获取所有文件名的列表。我在s3里有两个桶。对于下面的一个bucket,代码返回所有文件名(超过1000个),但对于另一个bucket,同一代码只返回1000个文件名。我只是不明白发生了什么。 为什么一个bucket运行相同的代码而另一个bucket不运行相同的代码

我的bucket还有层次结构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());

我刚刚将上述代码更改为使用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());
List keyList=new ArrayList();
ObjectListing object=s3.listObjects(“bucket.new.test”);
keyList=object.getObjectSummaries();
object=s3.ListNextBatchOfObject(对象);
while(object.isTruncated()){
addAll(current.getObjectSummaries());
object=s3.ListNextBatchOfObject(当前);
}
addAll(object.getObjectSummaries());

在这之后,您可以简单地在listkeyList

上使用任何迭代器,如果您想要获得所有对象(超过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);

对于Scala开发人员来说,这里是一个递归函数,它使用官方的

import com.amazonaws.services.s3.AmazonS3Client
导入com.amazonaws.services.s3.model.{S3ObjectSummary,ObjectListing,GetObjectRequest}
导入scala.collection.JavaConversions.{collectionAsScalaIterable=>asScala}
defmap[T](s3:AmazonS3Client,bucket:String,prefix:String)(f:(S3ObjectSummary)=>T){
def扫描(acc:List[T],listing:ObjectListing):List[T]={
val summaries=asScala[S3ObjectSummary](listing.getObjectSummaries())
val mapped=(对于(摘要(s.getKey,s.getOwner))
将返回该bucket/前缀中的
(key,owner)
元组的完整列表

map(s3,“bucket”,“prefix”)(s=>println(s))

正如你通常通过改进@Abhishek的答案来接近的那样。 此代码略短,变量名是固定的

您必须获得对象列表, 将其内容添加到集合中, 然后从列表中获取下一批对象。 重复该操作,直到列表不会被截断

List keyList=new ArrayList();
ObjectListing objects=s3.listObjects(“bucket.new.test”);
addAll(objects.getObjectSummaries());
while(objects.isTruncated()){
objects=s3.listenxtbatchofobjects(objects);
addAll(objects.getObjectSummaries());
}
  • Paolo Angioletti的代码无法获取所有数据,只能获取最后一批数据
  • 我认为使用ListBuffer可能更好
  • 此方法不支持设置startAfterKey
  • import com.amazonaws.services.s3.AmazonS3Client
    导入com.amazonaws.services.s3.model.{ObjectListing,S3ObjectSummary}
    导入scala.collection.JavaConverters_
    导入scala.collection.mutable.ListBuffer
    defmap[T](s3:AmazonS3Client,bucket:String,prefix:String)(f:(S3ObjectSummary)=>T):列表[T]={
    def扫描(acc:ListBuffer[T],列表:ObjectListing):列表[T]={
    val r=acc++=listing.getObjectSummaries.asScala.map(f).toList
    if(listing.isTruncated)扫描(r,s3.listenxtbatchofobjects(listing))
    托利斯特酒店
    }
    扫描(ListBuffer.empty[T],s3.listObjects(bucket,前缀))
    }
    
    第二种方法是使用awssdk-v2

    
    software.amazon.awssdk
    s3
    2.1.0
    
    import software.amazon.awssdk.services.s3.S3Client
    导入software.amazon.awssdk.services.s3.model.{ListObjectsV2Request,S3Object}
    导入scala.collection.JavaConverters_
    def listObjects[T](s3:s3客户端,bucket:String,
    前缀:String,startAfter:String)(f:(S3Object)=>T:List[T]={
    val request=ListObjectsV2Request.builder()
    .bucket(bucket).前缀(prefix)
    .startAfter(startAfter.build())
    s3.listObjectsV2Paginator(请求)
    阿斯卡拉先生
    .flatMap(u.contents().asScala)
    .地图(f)
    托利斯先生
    }
    
    在Scala中:

    val first = s3.listObjects("bucket.new.test")
    
    val listings: Seq[ObjectListing] = Iterator.iterate(Option(first))(_.flatMap(listing =>
      if (listing.isTruncated) Some(s3.listNextBatchOfObjects(listing))
      else None
    ))
      .takeWhile(_.nonEmpty)
      .toList
      .flatten
    

    默认情况下,API最多返回1000个键名。响应可能包含较少的键,但不会包含更多的键。 更好的实现是使用较新的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());
    
    List docList=new ArrayList();
    ListObjectsV2Request req=新的ListObjectsV2Request()。带bucketName(bucketName)。带前缀(folderFullPath);
    ListObjectsV2Result列表;
    做{
    清单=this.getAmazonS3Client().listObjectsV2(req);
    addAll(listing.getObjectSummaries());
    String token=listing.getNextContinuationToken();
    请求setContinuationToken(令牌);
    LOG.info(“列表文档的下一个延续标记为:“+标记”);
    }while(listing.isTruncated());
    
    由@oferei给出的代码运行良好,我支持该代码。但我想指出@Abhishek代码的根本问题。实际上,问题在于您的do-while循环。

    如果仔细观察,您将在最后二条语句中获取下一批对象,然后检查是否已耗尽文件的总列表变为false,则中断循环,不处理最后的X%1000条记录。例如:如果总共有2123条记录,则最终将获取1000条,然后是1000条,即2000条记录。您将错过123条记录,因为在检查isTruncated值后处理下一批时,isTruncated值将中断循环


    抱歉,我不能发表评论,否则我会对投票结果发表评论。

    我建议使用keyList.addAll(x)而不是分配给keyList。这样你就不会修改ObjectList的私有成员
    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());