AWS S3 SDK有没有下载整个文件夹下所有文件或获取到所有文件路径的方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AWS S3 SDK有没有下载整个文件夹下所有文件或获取到所有文件路径的方法相关的知识,希望对你有一定的参考价值。

如题

问题1:刷新一下你的项目就能看到了,你复制的时候应该是直接打开项目文件夹,找到存放图片的文件夹复制进去的对吧?其实你可以把复制的图片在vs里直接复制,那样不用刷新
问题2:获得存放图片文件夹的路径,月夜飞鹰的是个好主意,另外还可以自己直接定位,如果你要获得此文件夹路径的文件和文件夹在同意路径下,你就 /文件夹名 就行,如果是在下级目录,你就 /..文件夹
就行。
参考技术A

s3cmd sync LOCAL_DIR s3://BUCKET[/PREFIX] or s3://BUCKET[/PREFIX] LOCAL_DIR

# 下载目录到本地

s3cmd sync s3://BUCKET[/PREFIX] LOCAL_DIR

如何强制删除 S3 存储桶中的所有对象版本,然后最终使用 aws-sdk-go 删除整个存储桶?

【中文标题】如何强制删除 S3 存储桶中的所有对象版本,然后最终使用 aws-sdk-go 删除整个存储桶?【英文标题】:How to force delete all versions of objects in S3 bucket and then eventually delete the entire bucket using aws-sdk-go? 【发布时间】:2020-06-14 01:42:34 【问题描述】:

我有一个启用了版本控制的 S3 存储桶。存储桶几乎没有具有版本的文件。我编写了一个示例 golang 程序,它可以执行以下操作:

GetBucketVersioning - 可以获取桶的版本控制状态,即启用 ListObjects - 可以列出桶对象 DeleteObjects - 它可以删除存储桶对象(但它只是将“删除标记”添加到每个对象的最新版本。对象的版本历史仍然保持未删除) DeleteBucket:此操作失败并显示错误消息:

“BucketNotEmpty:您尝试删除的存储桶不为空。 您必须删除存储桶中的所有版本。”

您能否建议如何在 S3 存储桶中强制删除 ALL VERSIONS of ALL OBJECTS,以便我最终可以使用 aws-sdk-go 删除整个存储桶?

【问题讨论】:

先删除所有对象版本。 Java 中的示例:docs.aws.amazon.com/AmazonS3/latest/dev/… 【参考方案1】:

使用 golang sdk 这似乎是不可能的。 他们没有实现删除版本功能。

【讨论】:

可以使用版本号子资源。【参考方案2】:

根据文档,DeleteBucket 状态,

必须先删除存储桶中的所有对象(包括所有对象版本和删除标记),然后才能删除存储桶本身。

现在,要从启用版本控制的存储桶中删除版本,我们可以

    使用DeleteObject,其中指出,

要删除特定版本,您必须是存储桶所有者并且必须使用版本 ID 子资源。使用此子资源会永久删除该版本。

    使用DeleteObjects,同样声明,

在 XML 中,如果您想从启用了版本控制的存储桶中删除对象的特定版本,您可以提供对象键名称和可选的版本 ID。

在使用以下命令(先决条件 - Docker、Docker Compose、AWS CLI)创建存储桶并使用包含版本的文件填充它之后,我整理了一个示例程序,并针对 LocalStack 进行了测试。

curl -O https://raw.githubusercontent.com/localstack/localstack/master/docker-compose.yml
export SERVICES="s3"
docker-compose up

export AWS_ACCESS_KEY_ID="test"
export AWS_SECRET_ACCESS_KEY="test"
export AWS_DEFAULT_REGION="us-east-1"
aws --endpoint-url=http://localhost:4566 s3 mb s3://testbucket
aws --endpoint-url=http://localhost:4566 s3api put-bucket-versioning --bucket testbucket --versioning-configuration Status=Enabled
for i in 1 2 3; do
    aws --endpoint-url=http://localhost:4566 s3 cp main.go s3://testbucket/main.go
    aws --endpoint-url=http://localhost:4566 s3 cp go.mod s3://testbucket/go.mod
done

aws --endpoint-url=http://localhost:4566 s3api list-object-versions --bucket testbucket

在运行前设置以下环境变量

export AWS_ENDPOINT="http://localhost:4566"
export S3_BUCKET="testbucket"
package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "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"
    "github.com/aws/aws-sdk-go-v2/service/s3/types"
)

type s3Client struct 
    *s3.Client


func main() 
    awsEndpoint := os.Getenv("AWS_ENDPOINT")
    bucketName := os.Getenv("S3_BUCKET")

    cfg, err := config.LoadDefaultConfig(context.TODO(),
        config.WithEndpointResolverWithOptions(aws.EndpointResolverWithOptionsFunc(
            func(service, region string, options ...interface) (aws.Endpoint, error) 
                return aws.Endpoint
                    URL:               awsEndpoint,
                    HostnameImmutable: true,
                , nil
            )),
    )
    if err != nil 
        log.Fatalf("Cannot load the AWS configs: %s", err)
    

    serviceClient := s3.NewFromConfig(cfg)

    client := &s3Client
        Client: serviceClient,
    

    fmt.Printf(">>> Bucket: %s\n", bucketName)

    objects, err := client.listObjects(bucketName)
    if err != nil 
        log.Fatal(err)
    
    if len(objects) > 0 
        fmt.Printf(">>> List objects in the bucket: \n")
        for _, object := range objects 
            fmt.Printf("%s\n", object)
        
     else 
        fmt.Printf(">>> No objects in the bucket.\n")
    

    if client.versioningEnabled(bucketName) 
        fmt.Printf(">>> Versioning is enabled.\n")
        objectVersions, err := client.listObjectVersions(bucketName)
        if err != nil 
            log.Fatal(err)
        
        if len(objectVersions) > 0 
            fmt.Printf(">>> List objects with versions: \n")
            for key, versions := range objectVersions 
                fmt.Printf("%s: ", key)
                for _, version := range versions 
                    fmt.Printf("\n\t%s ", version)
                
                fmt.Println()
            
        

        if len(objectVersions) > 0 
            fmt.Printf(">>> Delete objects with versions.\n")
            if err := client.deleteObjects(bucketName, objectVersions); err != nil 
                log.Fatal(err)
            

            objectVersions, err = client.listObjectVersions(bucketName)
            if err != nil 
                log.Fatal(err)
            
            if len(objectVersions) > 0 
                fmt.Printf(">>> List objects with versions after deletion: \n")
                for key, version := range objectVersions 
                    fmt.Printf("%s: %s\n", key, version)
                
             else 
                fmt.Printf(">>> No objects in the bucket after deletion.\n")
            
        
    

    fmt.Printf(">>> Delete the bucket.\n")
    if err := client.deleteBucket(bucketName); err != nil 
        log.Fatal(err)
    



func (c *s3Client) versioningEnabled(bucket string) bool 
    output, err := c.GetBucketVersioning(context.TODO(), &s3.GetBucketVersioningInput
        Bucket: aws.String(bucket),
    )
    if err != nil 
        return false
    
    return output.Status == "Enabled"


func (c *s3Client) listObjects(bucket string) ([]string, error) 
    var objects []string
    output, err := c.ListObjectsV2(context.TODO(), &s3.ListObjectsV2Input
        Bucket: aws.String(bucket),
    )
    if err != nil 
        return nil, err
    

    for _, object := range output.Contents 
        objects = append(objects, aws.ToString(object.Key))
    

    return objects, nil


func (c *s3Client) listObjectVersions(bucket string) (map[string][]string, error) 
    var objectVersions = make(map[string][]string)
    output, err := c.ListObjectVersions(context.TODO(), &s3.ListObjectVersionsInput
        Bucket: aws.String(bucket),
    )
    if err != nil 
        return nil, err
    

    for _, object := range output.Versions 
        if _, ok := objectVersions[aws.ToString(object.Key)]; ok 
            objectVersions[aws.ToString(object.Key)] = append(objectVersions[aws.ToString(object.Key)], aws.ToString(object.VersionId))
         else 
            objectVersions[aws.ToString(object.Key)] = []stringaws.ToString(object.VersionId)
        
    

    return objectVersions, err


func (c *s3Client) deleteObjects(bucket string, objectVersions map[string][]string) error 
    var identifiers []types.ObjectIdentifier
    for key, versions := range objectVersions 
        for _, version := range versions 
            identifiers = append(identifiers, types.ObjectIdentifier
                Key:       aws.String(key),
                VersionId: aws.String(version),
            )
        
    

    _, err := c.DeleteObjects(context.TODO(), &s3.DeleteObjectsInput
        Bucket: aws.String(bucket),
        Delete: &types.Delete
            Objects: identifiers,
        ,
    )
    if err != nil 
        return err
    
    return nil


func (c *s3Client) deleteBucket(bucket string) error 
    _, err := c.DeleteBucket(context.TODO(), &s3.DeleteBucketInput
        Bucket: aws.String(bucket),
    )
    if err != nil 
        return err
    

    return nil

注意在listObjectVersions 方法中,我将VersionIds 映射到Keys。

    for _, object := range output.Versions 
        if _, ok := objectVersions[aws.ToString(object.Key)]; ok 
            objectVersions[aws.ToString(object.Key)] = append(objectVersions[aws.ToString(object.Key)], aws.ToString(object.VersionId))
         else 
            objectVersions[aws.ToString(object.Key)] = []stringaws.ToString(object.VersionId)
        
    

然后在deleteObjects方法中,当传递ObjectIdentifiers时,我为一个对象的所有版本传递KeyObjectIds。

    for key, versions := range objectVersions 
        for _, version := range versions 
            identifiers = append(identifiers, types.ObjectIdentifier
                Key:       aws.String(key),
                VersionId: aws.String(version),
            )
        
    

【讨论】:

以上是关于AWS S3 SDK有没有下载整个文件夹下所有文件或获取到所有文件路径的方法的主要内容,如果未能解决你的问题,请参考以下文章

golang aws-sdk-go 之 s3 服务

百度的Ueditor(php)上传到aws s3存储方案

百度的Ueditor(php)上传到aws s3存储方案

AWS S3 IOS中的混乱sdk?

如何使用AWS SDK从S3下载对象--RESTful。

如何使用AWS SDK从S3下载对象--RESTful。