AWS S3 – 列出没有前缀的文件夹中的所有对象

我在检索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中是否有方法。

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

http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/model/S3ObjectSummary.html

最好的办法是用“/”分割并取出数组中的最后一个对象。

对于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)) } 

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

例如

 map(s3, bucket, prefix) { s => println(s.getKey.split("/")(1)) } 

将打印所有文件名(不带前缀)

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

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

 val totalSize = map(s3, "bucket", "prefix")(s => s.getSize).sum 

将返回其内容的总大小(注意在表达式结尾处应用的额外sum()折叠函数;-)

您可以将map()与许多其他函数结合使用, 就像Monads在函数式编程中通常所采用的那样

只是为了跟进上面的评论 – “这里是执行完整扫描和映射的递归函数” – 如果存储桶中有超过1000个密钥,则代码中存在一个错误(如@Eric突出显示)。 修复实际上非常简单,需要将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)) } 

这段代码帮助我找到我的桶的子目录。

示例: – “Testing”是我的存储桶名称,其中包含“kdblue@gmail.com”文件夹,然后包含“IMAGE”文件夹,其中包含图像文件。

  ArrayList transferRecord = new ArrayList<>(); ListObjectsRequest listObjectsRequest = new ListObjectsRequest() .withBucketName(Constants.BUCKET_NAME) .withPrefix("kdblue@gmail.com" + "/IMAGE"); ObjectListing objects = s3.listObjects(listObjectsRequest); for (;;) { List summaries = objects.getObjectSummaries(); if (summaries.size() < 1) { break; } for(int i=0;i file = new ArrayList<>(); file.add(summaries.get(i).getKey()); transferRecord.add(file); } objects = s3.listNextBatchOfObjects(objects); } 

我希望这可以帮助你。

剪下来对我来说效果很好。 参考: https : //codeflex.co/get-list-of-objects-from-s3-directory/

  List getObjectslistFromFolder(String bucketName, String folderKey, AmazonS3 s3Client) { ListObjectsRequest listObjectsRequest = new ListObjectsRequest().withBucketName(bucketName) .withPrefix(folderKey + "/"); List keys = new ArrayList(); ObjectListing objects = s3Client.listObjects(listObjectsRequest); for (;;) { List 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;