AWS S3 ListObjectsV2返回文件夹对象问题求助
解决AWS S3 ListObjectsV2返回空目录对象的问题
问题场景
要列出S3存储桶中Folder1/Folder2/Folder3/路径下的所有文件,使用Go语言调用ListObjectsV2接口,设置Prefix参数后,返回结果里除了目标文件,还包含一个Size为0、Key为Folder1/Folder2/Folder3/的对象;添加Delimiter: "/"参数后,该空对象依然出现在返回结果中。
原调用代码:
params := &s3.ListObjectsV2Input{ Bucket: aws.String(os.Getenv("S3_USER_BUCKET")), Prefix: aws.String(key + loc[0] + "/"), } resp, _ := svc.ListObjectsV2(params)
返回结果:
Contents: [{ ETag: "\"TAG\"", Key: "Folder1/Folder2/Folder3/", LastModified: 2023-03-02 17:32:17 +0000 UTC, Size: 0, StorageClass: "STANDARD" },{ ETag: "\"TAG\"", Key: "Folder1/Folder2/Folder3/file", LastModified: 2023-03-02 17:32:30 +0000 UTC, Size: 106808, StorageClass: "STANDARD" }], IsTruncated: false, KeyCount: 2, MaxKeys: 1000, Name: "BUCKET", Prefix: "Folder1/Folder2/Folder3/"
添加Delimiter后的代码:
params := &s3.ListObjectsV2Input{ Bucket: aws.String(os.Getenv("S3_USER_BUCKET")), Prefix: aws.String(key + loc[0] + "/"), Delimiter: aws.String("/"), } resp, _ := svc.ListObjectsV2(params)
原因分析
这个Size为0的Folder1/Folder2/Folder3/对象是手动创建的占位符对象。S3本身没有真实目录结构,所谓的"目录"只是Key中的前缀,但如果通过控制台手动创建目录,或者调用API上传一个Key以"/"结尾、Size为0的对象,S3会将其作为真实对象存储,因此ListObjectsV2会把它和普通文件对象一起返回,Delimiter参数无法过滤掉这种真实存在的对象(Delimiter仅用于区分自动生成的前缀分组,而非真实对象)。
解决方案
1. 在代码中过滤结果
遍历返回的Contents列表,排除掉Key以"/"结尾且Size为0的对象:
import "strings" // ... params := &s3.ListObjectsV2Input{ Bucket: aws.String(os.Getenv("S3_USER_BUCKET")), Prefix: aws.String(key + loc[0] + "/"), } resp, err := svc.ListObjectsV2(params) if err != nil { // 处理错误逻辑 } // 过滤空目录占位符对象 var targetFiles []types.Object for _, obj := range resp.Contents { if *obj.Size != 0 || !strings.HasSuffix(*obj.Key, "/") { targetFiles = append(targetFiles, obj) } } // targetFiles中仅保留真实文件对象
2. 删除S3中的空目录占位符
如果不需要这些占位符对象,可以直接在S3控制台或通过API删除Folder1/Folder2/Folder3/这个Key对应的对象,之后调用ListObjectsV2时就不会再返回该空对象。
内容的提问来源于stack exchange,提问作者HLT
相关产品推荐
相关产品推荐

