如何使用AWS SDK for Go v2计算Amazon S3中模拟文件夹的大小?
Great question! Since Amazon S3 doesn't have actual folder structures—those "folders" you see in the console or UI are just visual abstractions built from object keys that contain / characters—there's no direct API call to get the total size of a simulated folder. You do need to list all objects under the target prefix and sum their individual sizes to get the total.
Why no direct API?
S3 stores all objects in a flat namespace; the "folder" is just part of an object's key. There's no dedicated metadata or entity for these simulated folders that tracks their cumulative size. So the only way to get the total is to iterate through every object under your target prefix and add up their Size values.
Example with AWS SDK for Go v2
Here's a practical example that uses the SDK's paginator to handle large numbers of objects (since ListObjectsV2 returns a max of 1000 objects per call):
package main import ( "context" "fmt" "log" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/s3" ) func calculateSimulatedFolderSize(bucketName, folderPrefix string) (int64, error) { // Load default AWS config (uses environment variables, ~/.aws/credentials, etc.) cfg, err := config.LoadDefaultConfig(context.TODO()) if err != nil { return 0, fmt.Errorf("failed to load SDK config: %w", err) } s3Client := s3.NewFromConfig(cfg) var totalSize int64 = 0 // Set up paginator to list all objects under the prefix paginator := s3.NewListObjectsV2Paginator(s3Client, &s3.ListObjectsV2Input{ Bucket: aws.String(bucketName), Prefix: aws.String(folderPrefix), // Optional: Use Delimiter to exclude the empty "folder marker" objects (if you created them) Delimiter: aws.String("/"), }) // Iterate through all pages of results for paginator.HasMorePages() { page, err := paginator.NextPage(context.TODO()) if err != nil { return 0, fmt.Errorf("failed to fetch page of objects: %w", err) } // Sum the size of each object in the current page for _, obj := range page.Contents { totalSize += *obj.Size } } return totalSize, nil } func main() { // Replace with your bucket and simulated folder prefix (don't forget the trailing slash!) bucket := "your-bucket-name" folderPrefix := "photos/vacation-2024/" size, err := calculateSimulatedFolderSize(bucket, folderPrefix) if err != nil { log.Fatalf("Error calculating folder size: %v", err) } fmt.Printf("Total size of simulated folder '%s': %d bytes\n", folderPrefix, size) }
Key Notes
- Trailing Slash: Always end your prefix with
/—otherwise, you might accidentally include objects with keys that start with your prefix but aren't part of the "folder" (e.g.,photos/vacationandphotos/vacation-photo.jpgwould both matchphotos/vacationwithout the slash). - Empty Folder Markers: If you created empty "folders" via the S3 console, those are zero-size objects with keys ending in
/. TheDelimiter: "/"parameter skips these markers; remove it if you want to include their (tiny) size in the total. - Pagination: The paginator automatically handles fetching all pages of results, which is essential if your "folder" has more than 1000 objects.
内容的提问来源于stack exchange,提问作者asanchez

