对象存储

  • 对象存储 > 使用指南 > 开发指南 > AWS S3 兼容 > 兼容 SDK 示例 > 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))
    	}
    }
    
    以上内容是否对您有帮助?
  • Qvm free helper
    Close