导入 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))
}
}
文档反馈
(如有产品使用问题,请 提交工单)