如何使用scala和aws-java-sdk从S3存储桶中获取所有S3ObjectSummary?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用scala和aws-java-sdk从S3存储桶中获取所有S3ObjectSummary?相关的知识,希望对你有一定的参考价值。

我有一个scala项目,我尝试实现一个需要访问Amazon S3存储桶的服务。

我想得到一个桶的所有对象的列表,但s3Client.listObjects的结果集被分页到1000个项目。

必须获取多个objectListings才能获得所有结果。

我发现了一个example Java implementation但它依赖于可变性(覆盖while循环中的objectListing):

AmazonS3 s3Client = AmazonS3Provider.getS3Client();
ListObjectsRequest req = new ListObjectsRequest().withBucketName(realBucket).withPrefix(!preprefix.equals("") ? preprefix + "/" + prefix : prefix);
ObjectListing objectListing = s3Client.listObjects(req);
List<S3ObjectSummary> summaries = objectListing.getObjectSummaries();

while (objectListing.isTruncated()) {
    objectListing = s3Client.listNextBatchOfObjects(objectListing);
    summaries.addAll(objectListing.getObjectSummaries());
}

虽然我可以将其翻译成scala,但我想使用更惯用的scala方式。

如何使用scala获取存储桶的所有页面?

答案

我现在使用递归方法并在每次迭代期间填充结果对象。一旦到达最后一页,它将返回最终的集合。

相关部分发生在getAllSummaries方法中,我保留其他实现细节,以便它可以帮助其他人更容易地使其工作。 (我的AmazonS3Config是一个包含我的S3凭据的基本案例类。)

import com.amazonaws.auth.{AWSStaticCredentialsProvider, BasicAWSCredentials}
import com.amazonaws.regions.Regions
import com.amazonaws.services.s3.model.{ObjectListing, S3ObjectSummary}
import com.amazonaws.services.s3.{AmazonS3, AmazonS3ClientBuilder}

import scala.collection.JavaConverters._

object Starter extends App with Configurable {

  private lazy val client: AmazonS3 = createAmazonClient(this.config.s3)

  val objects = getAllObjects()

  def getAllObjects(): Seq[S3ObjectSummary] = {
    val bucket = "YOUR_BUCKET_NAME"
    val prefix = ""

    val objectListing: ObjectListing = client.listObjects(bucket, prefix)

    getAllSummaries(objectListing)
  }

  private def getAllSummaries(list: ObjectListing,
                              res: Seq[S3ObjectSummary] = Seq.empty[S3ObjectSummary]): Seq[S3ObjectSummary] =
    list.isTruncated match {
      case false => {
        res ++ list.getObjectSummaries.asScala
      }
      case true =>
        val newList = this.client.listNextBatchOfObjects(list)
        getAllSummaries(newList, res ++ newList.getObjectSummaries.asScala)

    }

  private def createAmazonClient(config: AmazonS3Config): AmazonS3 = {
    val region = Regions.valueOf(config.region)
    val awsCredentials = new BasicAWSCredentials(config.accessKey, config.secretKey)

    AmazonS3ClientBuilder
      .standard()
      .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
      .withRegion(region)
      .build()
  }
}

以上是关于如何使用scala和aws-java-sdk从S3存储桶中获取所有S3ObjectSummary?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用aws-java-sdk从S3读取块的文件块

如何从 Apache Spark 访问 s3a:// 文件?

hadoop 2.7.7 的 AWS-Java-SDK 版本问题

Spark + S3 + IAM 角色

与 aws-java-sdk 链接时读取 json 文件时 Spark 崩溃

scala- 从 S3 存储桶读取文件