背景
AWS S3 并没有提供直接 API 获取桶或某个目录下的对象数量。
一个间接的方式是通过 ListObjectsV2 分页拉取所有对象然后计算出数量。
ListObjectsV2
ListObjectsV2 的 REST API 语法格式如下:
GET /?list-type=2&continuation-token=ContinuationToken&delimiter=Delimiter&encoding-type=EncodingType&fetch-owner=FetchOwner&max-keys=MaxKeys&prefix=Prefix&start-after=StartAfter HTTP/1.1
Host: Bucket.s3.amazonaws.com
x-amz-request-payer: RequestPayer
x-amz-expected-bucket-owner: ExpectedBucketOwner
其中有几个参数需要重点关注。
- max-keys
每个请求返回 bucket 中的部分或全部(最多1000个)对象。可以通过 max-keys 指定每次请求拉取的对象数量,有效取值范围是 1 到 1000。 - prefix
如果需要获取 bucket 中某个目录下的对象数量,可以通过 prefix 来指定对象的前缀。 - continuation-token
ListObjectsV2 采用的是深分页的方式拉取对象,所以使用类似 NextToken 的标识来进行分页操作。其中 continuation-token 在上一页请求返回中可以获取到。
回包中有一个字段需要重点关注。
IsTruncated 表示列表是否被截断。如果为 true 表示没有拉取完,如果为 false 表示已全部拉取。
Golang SDK 示例
下面以 S3 Golang SDK 为例,给出实现示例。
input := &s3.ListObjectsV2Input{
Bucket: aws.String("your-bucket-name"),
Prefix: aws.String("path/to/folder/"),
MaxKeys: aws.Int64(1000),
}
objectCount := 0
for {
resp, err := clt.ListObjectsV2(input)
if err != nil {
log.Fatal(err)
}
objectCount += len(resp.Contents)
fmt.Println("Objects Count:", objectCount)
if !*resp.IsTruncated {
break // Reach the end of the object listing
}
input.ContinuationToken = resp.NextContinuationToken
}
在上述示例中,我们首先将 MaxKeys 设置为 1000,然后使用循环调用 ListObjectsV2 API,直到返回的 IsTruncated 字段为 false,表示已经到达对象列表的末尾。在每次迭代中,我们累加返回的对象数量,并更新 ContinuationToken 以继续下一次分页调用。
通过使用分页机制,您可以逐步获取超过 1000 个对象,并在循环中处理每个分页的结果。这样,您就可以处理任意数量的对象,而不会超出 AWS S3 API 的限制。
关于 S3 客户端的初始化可以参考如下代码。
package main
import (
"log"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
)
func main() {
// 创建新的AWS会话
sess, err := session.NewSession(&aws.Config{
Region: aws.String("your-region"),
// 可选:提供凭证信息,或者SDK将尝试使用默认凭证。
// Credentials: credentials.NewStaticCredentials("your-access-key", "your-secret-key", ""),
})
if err != nil {
log.Fatal(err)
}
// 创建新的S3服务客户端
svc := s3.New(sess)
// 使用svc进行S3操作,例如上传、下载、删除对象等
// ...
// 关闭会话
sess.Close()
}
在上述示例中,您需要进行以下替换:
- “your-region”:替换为您的 AWS 区域代码,例如 “us-west-1”。
- “your-access-key"和"your-secret-key”:如果您没有将凭证信息设置为环境变量或配置文件中,可以取消注释并替换为您的AWS访问密钥ID和秘密访问密钥。
通过创建AWS会话和使用会话创建S3服务客户端,您可以使用Go客户端执行各种S3操作,如上传对象、下载对象、删除对象等。完成操作后,您可以关闭会话。
请确保您已经使用go get命令安装了github.com/aws/aws-sdk-go依赖,这样您就可以在您的代码中使用AWS S3 Go客户端。
参考文献
Amazon S3 API Reference - Amazon Simple Storage Service
Get the size of a folder in Amazon S3 using Go SDK 2