Java AWS S3-列出文件夹中不带前缀的所有对象

Java AWS S3-列出文件夹中不带前缀的所有对象,java,amazon-web-services,amazon-s3,Java,Amazon Web Services,Amazon S3,在AWS S3中检索文件夹中的所有对象(文件名)时遇到问题。这是我的密码: ListObjectsRequest listObjectsRequest = new ListObjectsRequest() .withBucketName(bucket) .withPrefix(folderName + "/") .withMarker(folderName + "/") ObjectListing objectLi

在AWS S3中检索文件夹中的所有对象(文件名)时遇到问题。这是我的密码:

ListObjectsRequest listObjectsRequest = new ListObjectsRequest()
            .withBucketName(bucket)
            .withPrefix(folderName + "/")
            .withMarker(folderName + "/")

    ObjectListing objectListing = amazonWebService.s3.listObjects(listObjectsRequest)

    for (S3ObjectSummary summary : objectListing.getObjectSummaries()) {
        print summary.getKey()
    }
它返回正确的对象,但带有前缀,例如foldename/filename


我知道我可以使用java substring来排除前缀,但我只是想知道AWS SDK中是否有用于前缀的方法。

没有。链接是所有可用方法的列表。这背后的原因是S3设计。S3没有“子文件夹”。相反,它只是一个文件列表,其中文件名是“前缀”加上您想要的文件名。GUI显示的数据类似于存储在“文件夹”中的windows,但S3中没有文件夹逻辑


您最好的选择是按“/”分割并获取数组中的最后一个对象

对于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=(对于(summary println(s.getKey.split(“/”)1)))
将打印所有文件名(不带前缀)

val tuple=map(s3,bucket,前缀)(s=>(s.getKey,s.getOwner,s.getSize))
将返回该bucket/前缀中的
(键、所有者、大小)
元组的完整列表

val totalSize=map(s3,“bucket”,“prefix”)(s=>s.getSize)
将返回其内容的总大小(请注意在表达式末尾应用的附加
sum()
折叠函数;-)


您可以将
map()
与许多其他函数结合起来,就像您通常通过来实现的那样,只是为了跟进上面的评论——“这里是执行完全扫描和映射的递归函数”——代码中有一个bug(如@Eric所强调的)如果bucket中有1000多个键。修复实际上非常简单,mapped.toList需要与acc合并

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

  def scan_s3_bucket(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) {
      acc ::: mapped.toList
    } else {
      println("list extended, more to go: new_keys '%s', current_length '%s'".format(mapped.length, acc.length))
      scan_s3_bucket(acc ::: mapped, s3.listNextBatchOfObjects(listing))
    }
  }

  scan_s3_bucket(List(), s3.listObjects(bucket, prefix))
}
defmap[T](s3:AmazonS3Client,bucket:String,前缀:String)(f:(S3ObjectSummary)=>T)={
def scan_s3_bucket(acc:List[T],listing:ObjectListing):List[T]={
val summaries=asScala[S3ObjectSummary](listing.getObjectSummaries())

val mapped=(for(summary此代码帮助我查找bucket的子目录

示例:-“Testing”是我的bucket名称,其中包含kdblue@gmail.com文件夹,然后它包含包含图像文件的“图像”文件夹

     ArrayList<String> transferRecord = new ArrayList<>();    

     ListObjectsRequest listObjectsRequest =
                            new ListObjectsRequest()
                                    .withBucketName(Constants.BUCKET_NAME)
                                    .withPrefix("kdblue@gmail.com" + "/IMAGE");

      ObjectListing objects = s3.listObjects(listObjectsRequest);
        for (;;) {
                    List<S3ObjectSummary> summaries = 
                    objects.getObjectSummaries();
                        if (summaries.size() < 1) {
                            break;
                        }

                       for(int i=0;i<summaries.size();i++){
                            ArrayList<String> file = new ArrayList<>();

                            file.add(summaries.get(i).getKey());
                            transferRecord.add(file);
                        }

                        objects = s3.listNextBatchOfObjects(objects);
               }
ArrayList transferRecord=new ArrayList();
ListObjectsRequest ListObjectsRequest=
新建ListObjectsRequest()
.withBucketName(常量.BUCKET_名称)
.withPrefix(“kdblue@gmail.com“+”/IMAGE”);
ObjectListing objects=s3.listObjects(listObjectsRequest);
对于(;;){
列表摘要=
getObjectSummaries();
if(summaries.size()<1){
打破
}

对于(int i=0;i,下面的剪报对我来说非常有效。参考:

列出getObjectslistFromFolder(字符串bucketName、字符串folderKey、AmazonS3 s3Client){
ListObjectsRequest ListObjectsRequest=新建ListObjectsRequest()。带bucketName(bucketName)
.带前缀(folderKey+“/”);
列表键=新的ArrayList();
ObjectListing objects=s3Client.listObjects(listObjectsRequest);
对于(;;){
List summaries=objects.getObjectSummaries();
if(summaries.size()<1){
打破
}
//summaries.forEach(s->keys.add(s.getKey());
//将项目合规性更改为jre 1.8
summaries.forEach(s->keys.add(s.getKey());
objects=s3Client.listNextBatchOfObjects(objects);
}
返回键;

此解决方案中存在错误。如果S3返回多个批次,此函数将只返回上一个批次的映射结果。一个修复方法是从扫描中删除累加器参数,并将条件更改为:If(!listing.isTruncated)mapped.toList else mapped::scan(S3.listNextBatchOfObjects(listing))@Eric感谢您的评论。这对生产项目至关重要,我没有发现Paolo在其初始函数中的错误。使用累加器时,它不会正确递归,它将级联只返回最终结果,而不是递归并将每次扫描附加到最终结果。
    List<String> getObjectslistFromFolder(String bucketName, String folderKey, AmazonS3 s3Client) {

    ListObjectsRequest listObjectsRequest = new ListObjectsRequest().withBucketName(bucketName)
            .withPrefix(folderKey + "/");

    List<String> keys = new ArrayList<String>();

    ObjectListing objects = s3Client.listObjects(listObjectsRequest);
    for (;;) {
        List<S3ObjectSummary> summaries = objects.getObjectSummaries();
        if (summaries.size() < 1) {
            break;
        }

        // summaries.forEach(s -> keys.add(s.getKey()));
        // changed project compliance to jre 1.8
        summaries.forEach(s -> keys.add(s.getKey()));

        objects = s3Client.listNextBatchOfObjects(objects);
    }

    return keys;