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

时间:2014-04-22 11:19:14

标签: java amazon-web-services amazon-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 /文件名

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

5 个答案:

答案 0 :(得分:6)

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

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

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

答案 1 :(得分:4)

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

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

例如

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

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

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()将{{1}}与许多其他功能结合起来Monads in Functional Programming

答案 2 :(得分:3)

此代码帮助我找到我的存储桶的子目录。

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

     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);
               }

我希望这会对你有所帮助。

答案 3 :(得分:2)

只是跟进上面的评论 - &#34;这里是执行完整扫描和映射的递归函数&#34; - 如果存储桶中有超过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))
}

答案 4 :(得分:0)

以下内容对我来说非常有效。参考:https://codeflex.co/get-list-of-objects-from-s3-directory/

    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;