使用SDK计数AWS S3存储桶中的对象时计数不正确

时间:2018-10-18 00:52:40

标签: java scala amazon-web-services amazon-s3 aws-sdk

我正在使用Scala这样计算AWS S3存储桶中的对象数:

val reqAws:ListObjectsV2Request = new ListObjectsV2Request().withBucketName(awsBucketName).withPrefix(prefixForAws);
var resultAws:ListObjectsV2Result = null;
var totalFilesInAws:Int = 0;
do {
  resultAws = awsS3Client.listObjectsV2(reqAws);
  val summariesForAws:java.util.List[S3ObjectSummary] = resultAws.getObjectSummaries()
  totalFilesInAws = totalFilesInAws + summariesForAws.size().toInt
  val token:String = resultAws.getNextContinuationToken();
  reqAws.setContinuationToken(token);
} while (resultAws.isTruncated());

但是它也给了我count那些不包含任何对象的前缀。

例如,如果我的前缀为a/b/c并且我的S3具有以下结构:

bucketName/a/b/c/d/obj1

bucketName/a/b/c/e/obj2

bucketName/a/b/c/f/

现在在这里我们可以看到a/b/c/f没有对象但是a/b/c/da/b/c/e却有对象,因此count应该是2,但是我的代码给出的计数是3

如何修改代码以获取正确的count

2 个答案:

答案 0 :(得分:1)

Amazon S3实际上没有文件夹/目录。

例如,您可以运行以下命令:

aws s3 cp foo.txt s3://my-bucket/a/b/c/foo.txt

即使路径a/b/c不存在,此方法仍然有效。

然后,如果该对象随后被删除,则路径消失。

这是因为每个对象的文件名(“键”)是完整路径。 Amazon S3使它看起来像有目录,但实际上没有目录。

那么,创建文件夹时会发生什么?答案是系统会创建一个长度为零的对象,其名称与路径相同。

在您的情况下,存在一个名为/a/b/c/f/的零长度对象。这使目录出现(即使没有目录也是如此)。

虽然a/b/c/f/可能包含一个对象,但是 是一个名为a/b/c/f/的对象。

该如何解决?这里有一些选择:

  • 不创建目录。让它们通过在给定路径中创建对象自动“出现”。这样,将没有目录名称的零长度文件。
  • 更改代码以忽略零长度的对象。

答案 1 :(得分:0)

我做了以下代码更改,现在我得到了正确的计数

val reqAws:ListObjectsV2Request = new ListObjectsV2Request().withBucketName(awsBucketName).withPrefix(prefixForAws);
var resultAws:ListObjectsV2Result = null;
var totalFilesInAws:Int = 0;
do {
  resultAws = awsS3Client.listObjectsV2(reqAws);
  val summariesForAws:java.util.List[S3ObjectSummary] = resultAws.getObjectSummaries()
  for(k <- summariesForAws.asScala) {
    if(!(k.getKey.toString().endsWith("/"))) {
      totalFilesInAws+= 1;
    }
  }
  val token:String = resultAws.getNextContinuationToken();
  reqAws.setContinuationToken(token);
} while (resultAws.isTruncated());