最近更新时间:2025-09-30 15:02:49
1. 该方法上传的单文件大小不能超过5GB,超过5GB的文件请使用分块上传 。
2. 使用预签名链接时,请注意请求头必须与生成链接时的请求头一致,否则会有签名不一致的问题。
以下代码用于简单上传:
package main
import (
"fmt"
"github.com/ks3sdklib/aws-sdk-go/aws"
"github.com/ks3sdklib/aws-sdk-go/aws/credentials"
"github.com/ks3sdklib/aws-sdk-go/service/s3"
"net/http"
"strings"
)
func main() {
// 创建访问凭证,请将<AccessKeyID>与<SecretAccessKey>替换成真正的值
cre := credentials.NewStaticCredentials("<AccessKeyID>", "<SecretAccessKey>", "")
// 创建S3Client,更多配置项请查看Go-SDK初始化文档
client := s3.New(&aws.Config{
Credentials: cre, // 访问凭证
Region: "BEIJING", // 填写您的Region
Endpoint: "ks3-cn-beijing.ksyuncs.com", // 填写您的Endpoint
})
// 填写存储空间名称
bucket := "<bucket_name>"
// 填写对象的key
key := "<object_key>"
// 生成上传外链
url, err := client.GeneratePresignedUrl(&s3.GeneratePresignedUrlInput{
HTTPMethod: s3.PUT, // 请求方法,可选值有 PUT, GET, DELETE, HEAD,必填
Bucket: aws.String(bucket), // 存储空间名称,必填
Key: aws.String(key), // 对象的key,必填
Expires: 3600, // 过期时间,例如,3600(表示1小时),必填
ACL: aws.String("public-read"), // 对象访问权限,非必填
ContentType: aws.String("text/plain"), // 文件类型,非必填
})
if err != nil {
panic(err)
}
fmt.Println("结果:\n", url)
// 通过外链上传,此处以Golang代码为例,也可以通过其他方式上传
httpReq, err := http.NewRequest("PUT", url, strings.NewReader("这是一段测试文本"))
if err != nil {
panic(err)
}
// 实际上传时的请求头必须与生成链接时的请求头一致,否则会有签名不一致的问题
httpReq.Header.Add("x-amz-acl", "public-read")
httpReq.Header.Add("Content-Type", "text/plain")
resp, err := http.DefaultClient.Do(httpReq)
if err != nil {
panic(err)
}
fmt.Println("上传结果:\n", *resp)
}1. 单文件大小超过5GB时必须采用分块上传。
2. 使用预签名链接时,请注意请求头必须与生成链接时的请求头一致,否则会有签名不一致的问题。
以下代码用于分块上传:
package main
import (
"fmt"
"github.com/ks3sdklib/aws-sdk-go/aws"
"github.com/ks3sdklib/aws-sdk-go/aws/awsutil"
"github.com/ks3sdklib/aws-sdk-go/aws/credentials"
"github.com/ks3sdklib/aws-sdk-go/service/s3"
"io"
"net/http"
"os"
"strconv"
)
func main() {
// 创建访问凭证,请将<AccessKeyID>与<SecretAccessKey>替换成真正的值
cre := credentials.NewStaticCredentials("<AccessKeyID>", "<SecretAccessKey>", "")
// 创建S3Client,更多配置项请查看Go-SDK初始化文档
client := s3.New(&aws.Config{
Credentials: cre, // 访问凭证
Region: "BEIJING", // 填写您的Region
Endpoint: "ks3-cn-beijing.ksyuncs.com", // 填写您的Endpoint
})
// 填写存储空间名称
bucket := "<bucket_name>"
// 填写对象的Key
key := "<object_key>"
// 1. 初始化分块上传
initRes, err := client.CreateMultipartUpload(&s3.CreateMultipartUploadInput{
Bucket: aws.String(bucket), // 存储空间名称,必填
Key: aws.String(key), // 对象的key,必填
})
if err != nil {
panic(err)
}
// 获取分块上传Id
uploadId := *initRes.UploadID
fmt.Println("init success, uploadId:", uploadId)
// 打开文件
file, err := os.Open("/Users/test/demo.txt")
if err != nil {
panic(err)
}
defer file.Close()
stat, err := file.Stat()
if err != nil {
panic(err)
}
var fileSize = stat.Size() // 文件大小
var partSize int64 = 5 * 1024 * 1024 // 分块大小为5MB
var compParts []*s3.CompletedPart // 已上传分块序号和etag信息,用于合并分块
var totalPartNum = (fileSize-1)/partSize + 1 // 计算总分块数
// 2. 分块上传
for partNum := int64(1); partNum <= totalPartNum; partNum++ {
offset := (partNum - 1) * partSize // 分块偏移量
actualPartSize := partSize
if offset+partSize >= fileSize {
actualPartSize = fileSize - offset
}
// 生成上传单个分块外链
url, err := client.GeneratePresignedUrl(&s3.GeneratePresignedUrlInput{
HTTPMethod: s3.PUT, // 请求方法,可选值有 PUT, GET, DELETE, HEAD, POST,必填
Bucket: aws.String(bucket), // 存储空间名称,必填
Key: aws.String(key), // 对象的key,必填
Expires: 3600, // 过期时间,例如,3600(表示1小时),必填
ExtendQueryParams: map[string]*string{
"partNumber": aws.String(strconv.FormatInt(partNum, 10)), // 分块序号,必填
"uploadId": aws.String(uploadId), // 分块上传ID,必填
},
})
if err != nil {
panic(err)
}
fmt.Printf("已生成第%d块上传外链, url:%s\n", partNum, url)
// 通过外链上传块,此处以Golang代码为例,也可以通过其他方式上传
request, err := http.NewRequest("PUT", url, io.NewSectionReader(file, offset, actualPartSize))
if err != nil {
panic(err)
}
// 发送请求
resp, err := http.DefaultClient.Do(request)
if err != nil {
panic(err)
}
if resp.StatusCode != 200 {
panic("上传失败")
}
// 已上传分块序号和etag信息,用于合并分块
etag := resp.Header.Get("ETag")
compParts = append(compParts, &s3.CompletedPart{PartNumber: aws.Long(partNum), ETag: aws.String(etag)})
fmt.Printf("已上传第%d块, etag:%s\n", partNum, etag)
}
// 3. 完成分块上传(合并分块)
compRes, _ := client.CompleteMultipartUpload(&s3.CompleteMultipartUploadInput{
Bucket: aws.String(bucket), // 存储空间名称,必填
Key: aws.String(key), // 对象的key,必填
UploadID: aws.String(uploadId), // 分块上传ID,必填
MultipartUpload: &s3.CompletedMultipartUpload{
Parts: compParts, // 已上传分块序号和etag信息,用于合并分块,必填
},
})
fmt.Println("结果:\n", awsutil.StringValue(compRes))
}
纯净模式
