【问题标题】:Amazon S3 Java API Only Downloads 50 ObjectsAmazon S3 Java API 仅下载 50 个对象
【发布时间】:2012-06-17 15:47:39
【问题描述】:

这让我很头疼,所以我想我会发布简单的解决方案。 我的问题是,在为 Amazon 的 S3 使用 Java API 时,我只能下载 50 个对象,然后它就会神秘地超时。代码看起来像这样:

int counter = 0;
AmazonS3Client s3 = new AmazonS3Client(propertiesFile);
while(objectList.isTruncated()){
for(S3ObjectSummary objectSummary : objectList.getObjectSummaries()){
    System.out.println(++counter);
    S3Object object = s3.getObject(new GetObjectRequest(bucketName, objectSummary.getKey()));
//do stuff
}
}

它将运行并处理恰好 50 个对象的所有内容,然后超时。

【问题讨论】:

    标签: java amazon-s3 amazon


    【解决方案1】:

    无论出于何种原因,主要问题是我已将 s3 声明为 AmazonS3Client s3。它应该看起来像:

    AmazonS3 s3 = new AmazonS3Client(propertiesFile);
    

    以防万一其他人遇到这个问题。

    【讨论】:

      【解决方案2】:

      希望虽然您可以调用 getObject 来下载它,但您并没有关闭 InputStream。这是通过调用 getObject() 来选择的;你必须在处理完每个对象后关闭 InputStream。

      更多详情请阅读:http://docs.amazonwebservices.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/AmazonS3Client.html#getObject(com.amazonaws.services.s3.model.GetObjectRequest)

      谢谢

      【讨论】:

        【解决方案3】:

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

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

        例如

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

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

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

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

        您可以将map() 与许多其他功能结合起来,就像您通常通过Monads in Functional Programming 处理的那样

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-11-08
          • 2016-02-21
          • 1970-01-01
          • 2019-02-12
          • 2015-12-24
          • 1970-01-01
          • 1970-01-01
          • 2017-06-18
          相关资源
          最近更新 更多