human: 如何处理七牛云的对象存储AWS SDK for Go

gpt: [对象存储](https://developer.qiniu.com/kodo) > 使用指南 >
[开发指南](https://developer.qiniu.com/kodo/development_guidelines/8596/development-
guidelines) > [AWS S3
兼容](https://developer.qiniu.com/kodo/development_guidelines/4086/aws-s3-compatible)
> [兼容 SDK 示例](https://developer.qiniu.com/kodo/development_guidelines/12553/S3
SDK sample) > AWS SDK for Go

#  AWS SDK for Go

最近更新时间: 2024-02-19 17:02:38

# 导入 AWS SDK for Go

确保 Go v1.15 或更新版本已经安装。

执行以下命令初始化 Go mod 项目

    
    
    go mod init example
    

然后添加 AWS SDK for Go 包

    
    
    go get github.com/aws/aws-sdk-go-v2@v1.21.0
    go get github.com/aws/aws-sdk-go-v2/config@v1.18.40
    go get github.com/aws/aws-sdk-go-v2/credentials@v1.13.38
    go get github.com/aws/aws-sdk-go-v2/feature/s3/manager@v1.11.84
    go get github.com/aws/aws-sdk-go-v2/service/s3@v1.38.5
    go get github.com/aws/aws-sdk-go-v2/service/sts@v1.22.0
    

对于之后的每个代码示例，将代码创建在 `main.go` 后，执行

    
    
    go run main.go
    

即可执行代码。

# 对象上传

## 获取客户端上传 URL

创建 `main.go`

    
    
    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/credentials"
    	"github.com/aws/aws-sdk-go-v2/service/s3"
    )
    
    func main() {
    	cfg, err := config.LoadDefaultConfig(
    		context.Background(),
    		config.WithCredentialsProvider(credentials.StaticCredentialsProvider{
    			Value: aws.Credentials{
    				AccessKeyID: "<QiniuAccessKey>", SecretAccessKey: "<QiniuSecretKey>",
    			},
    		}),
    		config.WithRegion("cn-east-1"), // 华东-浙江区 region id
    		config.WithEndpointResolverWithOptions(aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
    			return aws.Endpoint{
    				URL: "https://s3.cn-east-1.qiniucs.com", // 华东-浙江区 endpoint
    			}, nil
    		})))
    	if err != nil {
    		log.Fatalln(err)
    	}
    	s3Client := s3.NewFromConfig(cfg)
    	s3PresignClient := s3.NewPresignClient(s3Client)
    	req, err := s3PresignClient.PresignPutObject(context.Background(), &s3.PutObjectInput{
    		Bucket: aws.String("<Bucket>"),
    		Key:    aws.String("<Key>"),
    	})
    	if err != nil {
    		log.Fatalln(err)
    	}
    	fmt.Println(req.URL)
    }
    

这段代码将生成一个经过预先签名的客户端上传 URL，有效期为 15 分钟，客户端可以在有效时间内对该 URL 发送 HTTP PUT 请求将文件上传。

以下是用 curl 上传文件的案例：

    
    
    curl -X PUT --upload-file "<path/to/file>" "<presigned url>"
    

您也可以自行指定上传凭证的有效期，例如：

    
    
    package main
    
    import (
    	"context"
    	"fmt"
    	"log"
    	"time"
    
    	"github.com/aws/aws-sdk-go-v2/aws"
    	"github.com/aws/aws-sdk-go-v2/config"
    	"github.com/aws/aws-sdk-go-v2/credentials"
    	"github.com/aws/aws-sdk-go-v2/service/s3"
    )
    
    func main() {
    	cfg, err := config.LoadDefaultConfig(
    		context.Background(),
    		config.WithCredentialsProvider(credentials.StaticCredentialsProvider{
    			Value: aws.Credentials{
    				AccessKeyID: "<QiniuAccessKey>", SecretAccessKey: "<QiniuSecretKey>",
    			},
    		}),
    		config.WithRegion("cn-east-1"), // 华东-浙江区 region id
    		config.WithEndpointResolverWithOptions(aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
    			return aws.Endpoint{
    				URL: "https://s3.cn-east-1.qiniucs.com", // 华东-浙江区 endpoint
    			}, nil
    		})))
    	if err != nil {
    		log.Fatalln(err)
    	}
    	s3Client := s3.NewFromConfig(cfg)
    	s3PresignClient := s3.NewPresignClient(s3Client)
    	req, err := s3PresignClient.PresignPutObject(context.Background(), &s3.PutObjectInput{
    		Bucket: aws.String("<Bucket>"),
    		Key:    aws.String("<Key>"),
    	}, s3.WithPresignExpires(1*time.Hour)) // 有效期为一小时
    	if err != nil {
    		log.Fatalln(err)
    	}
    	fmt.Println(req.URL)
    }
    

## 服务器端直传

### 单请求上传（文件）

创建 `main.go`

    
    
    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/credentials"
    	"github.com/aws/aws-sdk-go-v2/service/s3"
    )
    
    func main() {
    	cfg, err := config.LoadDefaultConfig(
    		context.Background(),
    		config.WithCredentialsProvider(credentials.StaticCredentialsProvider{
    			Value: aws.Credentials{
    				AccessKeyID: "<QiniuAccessKey>", SecretAccessKey: "<QiniuSecretKey>",
    			},
    		}),
    		config.WithRegion("cn-east-1"), // 华东-浙江区 region id
    		config.WithEndpointResolverWithOptions(aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
    			return aws.Endpoint{
    				URL: "https://s3.cn-east-1.qiniucs.com", // 华东-浙江区 endpoint
    			}, nil
    		})))
    	if err != nil {
    		log.Fatalln(err)
    	}
    	s3Client := s3.NewFromConfig(cfg)
    
    	file, err := os.Open("<path/to/upload>")
    	if err != nil {
    		log.Fatalln(err)
    	}
    	defer file.Close()
    
    	output, err := s3Client.PutObject(context.Background(), &s3.PutObjectInput{
    		Bucket: aws.String("<Bucket>"),
    		Key:    aws.String("<Key>"),
    		Body:   file, // 这里也可以使用其他 io.Reader 实例实现对数据流的上传
    	})
    	if err != nil {
    		log.Fatalln(err)
    	}
    	fmt.Printf("ETag: %s\n", aws.ToString(output.ETag))
    }
    

### 单请求上传（数据流）

创建 `main.go`

    
    
    package main
    
    import (
    	"context"
    	"fmt"
    	"log"
    	"strings"
    
    	"github.com/aws/aws-sdk-go-v2/aws"
    	"github.com/aws/aws-sdk-go-v2/config"
    	"github.com/aws/aws-sdk-go-v2/credentials"
    	"github.com/aws/aws-sdk-go-v2/service/s3"
    )
    
    func main() {
    	cfg, err := config.LoadDefaultConfig(
    		context.Background(),
    		config.WithCredentialsProvider(credentials.StaticCredentialsProvider{
    			Value: aws.Credentials{
    				AccessKeyID: "<QiniuAccessKey>", SecretAccessKey: "<QiniuSecretKey>",
    			},
    		}),
    		config.WithRegion("cn-east-1"), // 华东-浙江区 region id
    		config.WithEndpointResolverWithOptions(aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
    			return aws.Endpoint{
    				URL: "https://s3.cn-east-1.qiniucs.com", // 华东-浙江区 endpoint
    			}, nil
    		})))
    	if err != nil {
    		log.Fatalln(err)
    	}
    	s3Client := s3.NewFromConfig(cfg)
    
    	output, err := s3Client.PutObject(context.Background(), &s3.PutObjectInput{
    		Bucket: aws.String("<Bucket>"),
    		Key:    aws.String("<Key>"),
    		Body:   strings.NewReader("Hello Qiniu S3!"),
    	})
    	if err != nil {
    		log.Fatalln(err)
    	}
    	fmt.Printf("ETag: %s\n", aws.ToString(output.ETag))
    }
    

### 分片上传（文件）

创建 `main.go`

    
    
    package main
    
    import (
    	"context"
    	"fmt"
    	"io"
    	"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/credentials"
    	"github.com/aws/aws-sdk-go-v2/service/s3"
    	"github.com/aws/aws-sdk-go-v2/service/s3/types"
    )
    
    func main() {
    	cfg, err := config.LoadDefaultConfig(
    		context.Background(),
    		config.WithCredentialsProvider(credentials.StaticCredentialsProvider{
    			Value: aws.Credentials{
    				AccessKeyID: "<QiniuAccessKey>", SecretAccessKey: "<QiniuSecretKey>",
    			},
    		}),
    		config.WithRegion("cn-east-1"), // 华东-浙江区 region id
    		config.WithEndpointResolverWithOptions(aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
    			return aws.Endpoint{
    				URL: "https://s3.cn-east-1.qiniucs.com", // 华东-浙江区 endpoint
    			}, nil
    		})))
    	if err != nil {
    		log.Fatalln(err)
    	}
    	s3Client := s3.NewFromConfig(cfg)
    
    	file, err := os.Open("<path/to/upload>")
    	if err != nil {
    		log.Fatalln(err)
    	}
    	defer file.Close()
    
    	fileInfo, err := file.Stat()
    	if err != nil {
    		log.Fatalln(err)
    	}
    
    	createMultipartUploadInput := s3.CreateMultipartUploadInput{
    		Bucket: aws.String("<Bucket>"),
    		Key:    aws.String("<Key>"),
    	}
    	createMultipartUploadOutput, err := s3Client.CreateMultipartUpload(context.Background(), &createMultipartUploadInput)
    	if err != nil {
    		log.Fatalln(err)
    	}
    	multipartUpload := types.CompletedMultipartUpload{}
    
    	const PART_SIZE int64 = 5 * 1024 * 1024 // 分片大小为 5 MB
    	// 这里给出的案例是串行分片上传。可以自行改造成并行分片上传以进一步提升上传速度
    	for uploaded, partNumber := int64(0), int32(1); uploaded < fileInfo.Size(); partNumber += 1 {
    		partSize := PART_SIZE
    		if partSize > fileInfo.Size()-uploaded {
    			partSize = fileInfo.Size() - uploaded
    		}
    		uploadPartOutput, err := s3Client.UploadPart(context.Background(), &s3.UploadPartInput{
    			Bucket:     createMultipartUploadInput.Bucket,
    			Key:        createMultipartUploadInput.Key,
    			UploadId:   createMultipartUploadOutput.UploadId,
    			PartNumber: partNumber,
    			Body:       &io.LimitedReader{R: file, N: partSize},
    		})
    		if err != nil {
    			log.Fatalln(err)
    		}
    		multipartUpload.Parts = append(multipartUpload.Parts, types.CompletedPart{PartNumber: partNumber, ETag: uploadPartOutput.ETag})
    		uploaded += partSize
    	}
    
    	completeMultipartUploadOutput, err := s3Client.CompleteMultipartUpload(context.Background(), &s3.CompleteMultipartUploadInput{
    		Bucket:          createMultipartUploadInput.Bucket,
    		Key:             createMultipartUploadInput.Key,
    		UploadId:        createMultipartUploadOutput.UploadId,
    		MultipartUpload: &multipartUpload,
    	})
    	if err != nil {
    		log.Fatalln(err)
    	}
    	fmt.Printf("ETag: %s\n", aws.ToString(completeMultipartUploadOutput.ETag))
    }
    

### 上传文件

创建 `main.go`

    
    
    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/credentials"
    	"github.com/aws/aws-sdk-go-v2/feature/s3/manager"
    	"github.com/aws/aws-sdk-go-v2/service/s3"
    )
    
    func main() {
    	cfg, err := config.LoadDefaultConfig(
    		context.Background(),
    		config.WithCredentialsProvider(credentials.StaticCredentialsProvider{
    			Value: aws.Credentials{
    				AccessKeyID: "<QiniuAccessKey>", SecretAccessKey: "<QiniuSecretKey>",
    			},
    		}),
    		config.WithRegion("cn-east-1"), // 华东-浙江区 region id
    		config.WithEndpointResolverWithOptions(aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
    			return aws.Endpoint{
    				URL: "https://s3.cn-east-1.qiniucs.com", // 华东-浙江区 endpoint
    			}, nil
    		})))
    	if err != nil {
    		log.Fatalln(err)
    	}
    	s3Client := s3.NewFromConfig(cfg)
    	s3Manager := manager.NewUploader(s3Client)
    
    	file, err := os.Open("<path/to/upload>")
    	if err != nil {
    		log.Fatalln(err)
    	}
    	defer file.Close()
    
    	output, err := s3Manager.Upload(context.Background(), &s3.PutObjectInput{
    		Bucket: aws.String("<Bucket>"),
    		Key:    aws.String("<Key>"),
    		Body:   file,
    	})
    	if err != nil {
    		log.Fatalln(err)
    	}
    	fmt.Printf("ETag: %s\n", aws.ToString(output.ETag))
    }
    

# 对象下载

## 获取客户端下载 URL

创建 `main.go`

    
    
    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/credentials"
    	"github.com/aws/aws-sdk-go-v2/service/s3"
    )
    
    func main() {
    	cfg, err := config.LoadDefaultConfig(
    		context.Background(),
    		config.WithCredentialsProvider(credentials.StaticCredentialsProvider{
    			Value: aws.Credentials{
    				AccessKeyID: "<QiniuAccessKey>", SecretAccessKey: "<QiniuSecretKey>",
    			},
    		}),
    		config.WithRegion("cn-east-1"), // 华东-浙江区 region id
    		config.WithEndpointResolverWithOptions(aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
    			return aws.Endpoint{
    				URL: "https://s3.cn-east-1.qiniucs.com", // 华东-浙江区 endpoint
    			}, nil
    		})))
    	if err != nil {
    		log.Fatalln(err)
    	}
    	s3Client := s3.NewFromConfig(cfg)
    	s3PresignClient := s3.NewPresignClient(s3Client)
    	req, err := s3PresignClient.PresignGetObject(context.Background(), &s3.GetObjectInput{
    		Bucket: aws.String("<Bucket>"),
    		Key:    aws.String("<Key>"),
    	})
    	if err != nil {
    		log.Fatalln(err)
    	}
    	fmt.Println(req.URL)
    }
    

这段代码将生成一个经过预先签名的客户端下载 URL，有效期为 15 分钟，客户端可以在有效时间内对该 URL 发送 HTTP GET 请求将文件下载。

以下是用 curl 下载文件的案例：

    
    
    curl -o "<path/to/download>" "<presigned url>"
    

您也可以自行指定上传凭证的有效期，例如：

    
    
    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/credentials"
    	"github.com/aws/aws-sdk-go-v2/service/s3"
    )
    
    func main() {
    	cfg, err := config.LoadDefaultConfig(
    		context.Background(),
    		config.WithCredentialsProvider(credentials.StaticCredentialsProvider{
    			Value: aws.Credentials{
    				AccessKeyID: "<QiniuAccessKey>", SecretAccessKey: "<QiniuSecretKey>",
    			},
    		}),
    		config.WithRegion("cn-east-1"), // 华东-浙江区 region id
    		config.WithEndpointResolverWithOptions(aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
    			return aws.Endpoint{
    				URL: "https://s3.cn-east-1.qiniucs.com", // 华东-浙江区 endpoint
    			}, nil
    		})))
    	if err != nil {
    		log.Fatalln(err)
    	}
    	s3Client := s3.NewFromConfig(cfg)
    	s3PresignClient := s3.NewPresignClient(s3Client)
    	req, err := s3PresignClient.PresignGetObject(context.Background(), &s3.GetObjectInput{
    		Bucket: aws.String("<Bucket>"),
    		Key:    aws.String("<Key>"),
    	}, s3.WithPresignExpires(1*time.Hour))
    	if err != nil {
    		log.Fatalln(err)
    	}
    	fmt.Println(req.URL)
    }
    

## 服务器端直接下载

创建 `main.go`

    
    
    package main
    
    import (
    	"context"
    	"fmt"
    	"io"
    	"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/credentials"
    	"github.com/aws/aws-sdk-go-v2/service/s3"
    )
    
    func main() {
    	cfg, err := config.LoadDefaultConfig(
    		context.Background(),
    		config.WithCredentialsProvider(credentials.StaticCredentialsProvider{
    			Value: aws.Credentials{
    				AccessKeyID: "<QiniuAccessKey>", SecretAccessKey: "<QiniuSecretKey>",
    			},
    		}),
    		config.WithRegion("cn-east-1"), // 华东-浙江区 region id
    		config.WithEndpointResolverWithOptions(aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
    			return aws.Endpoint{
    				URL: "https://s3.cn-east-1.qiniucs.com", // 华东-浙江区 endpoint
    			}, nil
    		})))
    	if err != nil {
    		log.Fatalln(err)
    	}
    	s3Client := s3.NewFromConfig(cfg)
    
    	file, err := os.OpenFile("<path/to/download>", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
    	if err != nil {
    		log.Fatalln(err)
    	}
    	defer file.Close()
    
    	output, err := s3Client.GetObject(context.Background(), &s3.GetObjectInput{
    		Bucket: aws.String("<Bucket>"),
    		Key:    aws.String("<Key>"),
    	})
    	if err != nil {
    		log.Fatalln(err)
    	}
    	defer output.Body.Close()
    
    	_, err = io.Copy(file, output.Body)
    	if err != nil {
    		log.Fatalln(err)
    	}
    
    	fmt.Printf("ETag: %s\n", aws.ToString(output.ETag))
    }
    

## 下载文件

创建 `main.go`

    
    
    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/credentials"
    	"github.com/aws/aws-sdk-go-v2/feature/s3/manager"
    	"github.com/aws/aws-sdk-go-v2/service/s3"
    )
    
    func main() {
    	cfg, err := config.LoadDefaultConfig(
    		context.Background(),
    		config.WithCredentialsProvider(credentials.StaticCredentialsProvider{
    			Value: aws.Credentials{
    				AccessKeyID: "<QiniuAccessKey>", SecretAccessKey: "<QiniuSecretKey>",
    			},
    		}),
    		config.WithRegion("cn-east-1"), // 华东-浙江区 region id
    		config.WithEndpointResolverWithOptions(aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
    			return aws.Endpoint{
    				URL: "https://s3.cn-east-1.qiniucs.com", // 华东-浙江区 endpoint
    			}, nil
    		})))
    	if err != nil {
    		log.Fatalln(err)
    	}
    	s3Client := s3.NewFromConfig(cfg)
    	s3Manager := manager.NewDownloader(s3Client)
    
    	file, err := os.OpenFile("<path/to/download>", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
    	if err != nil {
    		log.Fatalln(err)
    	}
    	defer file.Close()
    
    	_, err = s3Manager.Download(context.Background(), file, &s3.GetObjectInput{
    		Bucket: aws.String("<Bucket>"),
    		Key:    aws.String("<Key>"),
    	})
    	if err != nil {
    		log.Fatalln(err)
    	}
    
    	fmt.Println("Done")
    }
    

# 对象管理

## 获取对象信息

创建 `main.go`

    
    
    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/credentials"
    	"github.com/aws/aws-sdk-go-v2/service/s3"
    )
    
    func main() {
    	cfg, err := config.LoadDefaultConfig(
    		context.Background(),
    		config.WithCredentialsProvider(credentials.StaticCredentialsProvider{
    			Value: aws.Credentials{
    				AccessKeyID: "<QiniuAccessKey>", SecretAccessKey: "<QiniuSecretKey>",
    			},
    		}),
    		config.WithRegion("cn-east-1"), // 华东-浙江区 region id
    		config.WithEndpointResolverWithOptions(aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
    			return aws.Endpoint{
    				URL: "https://s3.cn-east-1.qiniucs.com", // 华东-浙江区 endpoint
    			}, nil
    		})))
    	if err != nil {
    		log.Fatalln(err)
    	}
    	s3Client := s3.NewFromConfig(cfg)
    
    	output, err := s3Client.HeadObject(context.Background(), &s3.HeadObjectInput{
    		Bucket: aws.String("<Bucket>"),
    		Key:    aws.String("<Key>"),
    	})
    	if err != nil {
    		log.Fatalln(err)
    	}
    	fmt.Printf("ETag: %s\n", aws.ToString(output.ETag))
    }
    

## 修改对象 MimeType

创建 `main.go`

    
    
    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/credentials"
    	"github.com/aws/aws-sdk-go-v2/service/s3"
    	"github.com/aws/aws-sdk-go-v2/service/s3/types"
    )
    
    func main() {
    	cfg, err := config.LoadDefaultConfig(
    		context.Background(),
    		config.WithCredentialsProvider(credentials.StaticCredentialsProvider{
    			Value: aws.Credentials{
    				AccessKeyID: "<QiniuAccessKey>", SecretAccessKey: "<QiniuSecretKey>",
    			},
    		}),
    		config.WithRegion("cn-east-1"), // 华东-浙江区 region id
    		config.WithEndpointResolverWithOptions(aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
    			return aws.Endpoint{
    				URL: "https://s3.cn-east-1.qiniucs.com", // 华东-浙江区 endpoint
    			}, nil
    		})))
    	if err != nil {
    		log.Fatalln(err)
    	}
    	s3Client := s3.NewFromConfig(cfg)
    
    	_, err = s3Client.CopyObject(context.Background(), &s3.CopyObjectInput{
    		Bucket:            aws.String("<Bucket>"),
    		Key:               aws.String("<Key>"),
    		CopySource:        aws.String("/<Bucket>/<Key>"),
    		ContentType:       aws.String("<NewContentType>"),
    		MetadataDirective: types.MetadataDirectiveReplace,
    	})
    	if err != nil {
    		log.Fatalln(err)
    	}
    	fmt.Println("Done")
    }
    

## 修改对象存储类型

创建 `main.go`

    
    
    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/credentials"
    	"github.com/aws/aws-sdk-go-v2/service/s3"
    	"github.com/aws/aws-sdk-go-v2/service/s3/types"
    )
    
    func main() {
    	cfg, err := config.LoadDefaultConfig(
    		context.Background(),
    		config.WithCredentialsProvider(credentials.StaticCredentialsProvider{
    			Value: aws.Credentials{
    				AccessKeyID: "<QiniuAccessKey>", SecretAccessKey: "<QiniuSecretKey>",
    			},
    		}),
    		config.WithRegion("cn-east-1"), // 华东-浙江区 region id
    		config.WithEndpointResolverWithOptions(aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
    			return aws.Endpoint{
    				URL: "https://s3.cn-east-1.qiniucs.com", // 华东-浙江区 endpoint
    			}, nil
    		})))
    	if err != nil {
    		log.Fatalln(err)
    	}
    	s3Client := s3.NewFromConfig(cfg)
    
    	_, err = s3Client.CopyObject(context.Background(), &s3.CopyObjectInput{
    		Bucket:            aws.String("<Bucket>"),
    		Key:               aws.String("<Key>"),
    		CopySource:        aws.String("/<Bucket>/<Key>"),
    		StorageClass:      types.StorageClassGlacier,
    		MetadataDirective: types.MetadataDirectiveReplace,
    	})
    	if err != nil {
    		log.Fatalln(err)
    	}
    	fmt.Println("Done")
    }
    

## 复制对象副本

创建 `main.go`

    
    
    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/credentials"
    	"github.com/aws/aws-sdk-go-v2/service/s3"
    	"github.com/aws/aws-sdk-go-v2/service/s3/types"
    )
    
    func main() {
    	cfg, err := config.LoadDefaultConfig(
    		context.Background(),
    		config.WithCredentialsProvider(credentials.StaticCredentialsProvider{
    			Value: aws.Credentials{
    				AccessKeyID: "<QiniuAccessKey>", SecretAccessKey: "<QiniuSecretKey>",
    			},
    		}),
    		config.WithRegion("cn-east-1"), // 华东-浙江区 region id
    		config.WithEndpointResolverWithOptions(aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
    			return aws.Endpoint{
    				URL: "https://s3.cn-east-1.qiniucs.com", // 华东-浙江区 endpoint
    			}, nil
    		})))
    	if err != nil {
    		log.Fatalln(err)
    	}
    	s3Client := s3.NewFromConfig(cfg)
    
    	_, err = s3Client.CopyObject(context.Background(), &s3.CopyObjectInput{
    		Bucket:            aws.String("<ToBucket>"),
    		Key:               aws.String("<ToKey>"),
    		CopySource:        aws.String("/<FromBucket>/<FromKey>"),
    		MetadataDirective: types.MetadataDirectiveCopy,
    	})
    	if err != nil {
    		log.Fatalln(err)
    	}
    	fmt.Println("Done")
    }
    

## 复制对象副本（大于 5GB）

创建 `main.go`

    
    
    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/credentials"
    	"github.com/aws/aws-sdk-go-v2/service/s3"
    	"github.com/aws/aws-sdk-go-v2/service/s3/types"
    )
    
    func main() {
    	cfg, err := config.LoadDefaultConfig(
    		context.Background(),
    		config.WithCredentialsProvider(credentials.StaticCredentialsProvider{
    			Value: aws.Credentials{
    				AccessKeyID: "<QiniuAccessKey>", SecretAccessKey: "<QiniuSecretKey>",
    			},
    		}),
    		config.WithRegion("cn-east-1"), // 华东-浙江区 region id
    		config.WithEndpointResolverWithOptions(aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
    			return aws.Endpoint{
    				URL: "https://s3.cn-east-1.qiniucs.com", // 华东-浙江区 endpoint
    			}, nil
    		})))
    	if err != nil {
    		log.Fatalln(err)
    	}
    	s3Client := s3.NewFromConfig(cfg)
    
    	headObjectInput := s3.HeadObjectInput{
            Bucket: aws.String("<ToBucket>"),
    		Key:    aws.String("<ToKey>"),
    	}
    	headObjectOutput, err := s3Client.HeadObject(context.Background(), &headObjectInput)
    	if err != nil {
    		log.Fatalln(err)
    	}
    
    	createMultipartUploadInput := s3.CreateMultipartUploadInput{
    		Bucket: aws.String("<FromBucket>"),
    		Key:    aws.String("<FromKey>"),
    	}
    	createMultipartUploadOutput, err := s3Client.CreateMultipartUpload(context.Background(), &createMultipartUploadInput)
    	if err != nil {
    		log.Fatalln(err)
    	}
    	multipartUpload := types.CompletedMultipartUpload{}
    
    	const PART_SIZE int64 = 5 * 1024 * 1024 // 分片大小为 5 MB
    	// 这里给出的案例是串行分片复制。可以自行改造成并行分片复制以进一步提升复制速度
    	for copied, partNumber := int64(0), int32(1); copied < headObjectOutput.ContentLength; partNumber += 1 {
    		partSize := PART_SIZE
    		if partSize > headObjectOutput.ContentLength-copied {
    			partSize = headObjectOutput.ContentLength - copied
    		}
    		uploadPartCopyOutput, err := s3Client.UploadPartCopy(context.Background(), &s3.UploadPartCopyInput{
    			Bucket:          createMultipartUploadInput.Bucket,
    			Key:             createMultipartUploadInput.Key,
    			UploadId:        createMultipartUploadOutput.UploadId,
    			PartNumber:      partNumber,
    			CopySource:      aws.String(fmt.Sprintf("/%s/%s", aws.ToString(headObjectInput.Bucket), aws.ToString(headObjectInput.Key))),
    			CopySourceRange: aws.String(fmt.Sprintf("bytes=%d-%d", copied, copied+partSize-1)),
    		})
    		if err != nil {
    			log.Fatalln(err)
    		}
    		multipartUpload.Parts = append(multipartUpload.Parts, types.CompletedPart{PartNumber: partNumber, ETag: uploadPartCopyOutput.CopyPartResult.ETag})
    		copied += partSize
    	}
    
    	completeMultipartUploadOutput, err := s3Client.CompleteMultipartUpload(context.Background(), &s3.CompleteMultipartUploadInput{
    		Bucket:          createMultipartUploadInput.Bucket,
    		Key:             createMultipartUploadInput.Key,
    		UploadId:        createMultipartUploadOutput.UploadId,
    		MultipartUpload: &multipartUpload,
    	})
    	if err != nil {
    		log.Fatalln(err)
    	}
    	fmt.Printf("ETag: %s\n", aws.ToString(completeMultipartUploadOutput.ETag))
    }
    

## 删除空间中的文件

创建 `main.go`

    
    
    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/credentials"
    	"github.com/aws/aws-sdk-go-v2/service/s3"
    )
    
    func main() {
    	cfg, err := config.LoadDefaultConfig(
    		context.Background(),
    		config.WithCredentialsProvider(credentials.StaticCredentialsProvider{
    			Value: aws.Credentials{
    				AccessKeyID: "<QiniuAccessKey>", SecretAccessKey: "<QiniuSecretKey>",
    			},
    		}),
    		config.WithRegion("cn-east-1"), // 华东-浙江区 region id
    		config.WithEndpointResolverWithOptions(aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
    			return aws.Endpoint{
    				URL: "https://s3.cn-east-1.qiniucs.com", // 华东-浙江区 endpoint
    			}, nil
    		})))
    	if err != nil {
    		log.Fatalln(err)
    	}
    	s3Client := s3.NewFromConfig(cfg)
    
    	_, err = s3Client.DeleteObject(context.Background(), &s3.DeleteObjectInput{
    		Bucket: aws.String("<Bucket>"),
    		Key:    aws.String("<Key>"),
    	})
    	if err != nil {
    		log.Fatalln(err)
    	}
    	fmt.Println("Done")
    }
    

## 获取指定前缀的文件列表

创建 `main.go`

    
    
    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/credentials"
    	"github.com/aws/aws-sdk-go-v2/service/s3"
    )
    
    func main() {
    	cfg, err := config.LoadDefaultConfig(
    		context.Background(),
    		config.WithCredentialsProvider(credentials.StaticCredentialsProvider{
    			Value: aws.Credentials{
    				AccessKeyID: "<QiniuAccessKey>", SecretAccessKey: "<QiniuSecretKey>",
    			},
    		}),
    		config.WithRegion("cn-east-1"), // 华东-浙江区 region id
    		config.WithEndpointResolverWithOptions(aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
    			return aws.Endpoint{
    				URL: "https://s3.cn-east-1.qiniucs.com", // 华东-浙江区 endpoint
    			}, nil
    		})))
    	if err != nil {
    		log.Fatalln(err)
    	}
    	s3Client := s3.NewFromConfig(cfg)
    
    	output, err := s3Client.ListObjectsV2(context.Background(), &s3.ListObjectsV2Input{
    		Bucket: aws.String("<Bucket>"),
    		Prefix: aws.String("<KeyPrefix>"),
    	})
    	if err != nil {
    		log.Fatalln(err)
    	}
    	for _, object := range output.Contents {
    		fmt.Printf("Key: %s\n", aws.ToString(object.Key))
    		fmt.Printf("ETag: %s\n", aws.ToString(object.ETag))
    	}
    }
    

## 批量删除空间中的文件

创建 `main.go`

    
    
    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/credentials"
    	"github.com/aws/aws-sdk-go-v2/service/s3"
    	"github.com/aws/aws-sdk-go-v2/service/s3/types"
    )
    
    func main() {
    	cfg, err := config.LoadDefaultConfig(
    		context.Background(),
    		config.WithCredentialsProvider(credentials.StaticCredentialsProvider{
    			Value: aws.Credentials{
    				AccessKeyID: "<QiniuAccessKey>", SecretAccessKey: "<QiniuSecretKey>",
    			},
    		}),
    		config.WithRegion("cn-east-1"), // 华东-浙江区 region id
    		config.WithEndpointResolverWithOptions(aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
    			return aws.Endpoint{
    				URL: "https://s3.cn-east-1.qiniucs.com", // 华东-浙江区 endpoint
    			}, nil
    		})))
    	if err != nil {
    		log.Fatalln(err)
    	}
    	s3Client := s3.NewFromConfig(cfg)
    
    	_, err = s3Client.DeleteObjects(context.Background(), &s3.DeleteObjectsInput{
    		Bucket: aws.String("<Bucket>"),
    		Delete: &types.Delete{
    			Objects: []types.ObjectIdentifier{
    				{Key: aws.String("<Key1>")},
    				{Key: aws.String("<Key2>")},
    				{Key: aws.String("<Key3>")},
    				{Key: aws.String("<Key4>")},
    			},
    		},
    	})
    	if err != nil {
    		log.Fatalln(err)
    	}
    	fmt.Println("Done")
    }
    

# 临时安全凭证

创建 `main.go`

    
    
    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/credentials"
    	"github.com/aws/aws-sdk-go-v2/service/s3"
    	"github.com/aws/aws-sdk-go-v2/service/sts"
    )
    
    func main() {
    	cfg, err := config.LoadDefaultConfig(
    		context.Background(),
    		config.WithCredentialsProvider(aws.NewCredentialsCache(aws.CredentialsProviderFunc(func(ctx context.Context) (aws.Credentials, error) {
    			cfg, err := config.LoadDefaultConfig(
    				ctx,
    				config.WithCredentialsProvider(credentials.StaticCredentialsProvider{
    					AccessKeyID: "<QiniuAccessKey>", SecretAccessKey: "<QiniuSecretKey>",
    				}),
    				config.WithRegion("cn-east-1"), // 华东-浙江区 region id
    				config.WithEndpointResolverWithOptions(aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
    					return aws.Endpoint{
    						URL: "https://s3.cn-east-1.qiniucs.com", // 华东-浙江区 endpoint
    					}, nil
    				})),
    			)
    			if err != nil {
    				return aws.Credentials{}, nil
    			}
    			federationToken, err := sts.NewFromConfig(cfg).GetFederationToken(ctx, &sts.GetFederationTokenInput{
    				Name:            aws.String("Bob"),
    				DurationSeconds: aws.Int32(3600),
    				Policy:          aws.String("{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"Stmt1\",\"Effect\":\"Allow\",\"Action\":[\"*\"],\"Resource\":[\"*\"]}]}"),
    			})
    			if err != nil {
    				return aws.Credentials{}, nil
    			}
    			return aws.Credentials{
    				AccessKeyID:     aws.ToString(federationToken.Credentials.AccessKeyId),
    				SecretAccessKey: aws.ToString(federationToken.Credentials.SecretAccessKey),
    				SessionToken:    aws.ToString(federationToken.Credentials.SessionToken),
    				Expires:         aws.ToTime(federationToken.Credentials.Expiration),
    				CanExpire:       true,
    			}, nil
    		}))),
    		config.WithRegion("cn-east-1"), // 华东-浙江区 region id
    		config.WithEndpointResolverWithOptions(aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
    			return aws.Endpoint{
    				URL: "https://s3.cn-east-1.qiniucs.com", // 华东-浙江区 endpoint
    			}, nil
    		})),
    	)
    	if err != nil {
    		log.Fatalln(err)
    	}
    
    	// 取得了 sts.GetFederationTokenOutput.Credentials 后，可以使用这些临时凭证调用 S3 服务
    	listBucketsOutput, err := s3.NewFromConfig(cfg).ListBuckets(context.Background(), &s3.ListBucketsInput{})
    	if err != nil {
    		log.Fatalln(err)
    	}
    	for _, bucket := range listBucketsOutput.Buckets {
    		fmt.Printf("%s\n", aws.ToString(bucket.Name))
    	}
    }
    

以上内容是否对您有帮助？