本文介绍使用 PreSignedURL 进行分片上传的过程。
TOS提供两种上传方式,简单上传跟分片上传,简单上传方式最大能够上传5GB的文件,所以如果对象大小超过5GB,需要使用分片上传实现。
使用分片上传,您可以将对象分成多个数据块(Part)分别上传,每个分片都是对象数据的连续部分。您可以独立上传以及按任意顺序上传这些对象分片。如果其中任意分片上传失败,可以重新进行上传且不影响其他分片。上传完所有分片后,汇集所有分片并创建元数据。
分片上传优势:
分片上传流程:
预签名 URL:
可以使用预签名 URL 提供 TOS 桶中对象的限时访问权限。可以直接使用预签名 URL 来下载对象;还可以使用预签名 URL 来允许用户将特定对象上传到 TOS 桶。使用预签名 URL 不要求用户拥有 TOS 凭证或权限,并且在到期日期之前,可以多次使用预签名 URL。
本实验将实现使用预签名进行分段上传的过程。
您可以使用如下命令安装Go SDK。
go get -u github.com/volcengine/ve-tos-golang-sdk/v2
示例代码如下:
package main import ( "context" "fmt" "github.com/volcengine/ve-tos-golang-sdk/v2/tos" "github.com/volcengine/ve-tos-golang-sdk/v2/tos/enum" ) func checkErr(err error) { if err != nil { if serverErr, ok := err.(*tos.TosServerError); ok { fmt.Println("Error:", serverErr.Error()) fmt.Println("Request ID:", serverErr.RequestID) fmt.Println("Response Status Code:", serverErr.StatusCode) fmt.Println("Response Header:", serverErr.Header) fmt.Println("Response Err Code:", serverErr.Code) fmt.Println("Response Err Msg:", serverErr.Message) } else if clientErr, ok := err.(*tos.TosClientError); ok { fmt.Println("Error:", clientErr.Error()) fmt.Println("Client Cause Err:", clientErr.Cause.Error()) } else { fmt.Println("Error:", err) } panic(err) } } func main() { var ( accessKey = "真实AK" secretKey = "真实SK" endpoint = "tos-cn-beijing.volces.com" region = "cn-beijing" // BucketName bucketName = "wanyix-1" // ObjectKey objectKey = "mul-lab-test" ctx = context.Background() ) // 初始化客户端 client, err := tos.NewClientV2(endpoint, tos.WithRegion(region), tos.WithCredentials(tos.NewStaticCredentials(accessKey, secretKey))) checkErr(err) // 初始化分片,指定对象权限为私有,存储类型为低频并设置元数据信息 createMultipartOutput, err := client.CreateMultipartUploadV2(ctx, &tos.CreateMultipartUploadV2Input{ Bucket: bucketName, Key: objectKey, ACL: enum.ACLPrivate, StorageClass: enum.StorageClassIa, Meta: map[string]string{"key": "value"}, }) checkErr(err) //fmt.Println("CreateMultipartUploadV2 Request ID:", createMultipartOutput.RequestID) // 获取到分片上传 UploadID fmt.Println("CreateMultipartUploadV2 Upload ID:", createMultipartOutput.UploadID) }
响应如下:
CreateMultipartUploadV2 Upload ID: 7443ad5cb011dd73cfd501db44a3ff10
完成后,可以拿到分片上传的ID。
package main import ( //"context" "fmt" "github.com/volcengine/ve-tos-golang-sdk/v2/tos" "github.com/volcengine/ve-tos-golang-sdk/v2/tos/enum" _ "strings" ) func checkErr(err error) { if err != nil { panic(err) } } func main() { var ( accessKey = "真实AK" secretKey = "真实SK" endpoint = "tos-cn-beijing.volces.com" region = "cn-beijing" ) client, err := tos.NewClientV2(endpoint, tos.WithRegion(region), tos.WithCredentials(tos.NewStaticCredentials(accessKey, secretKey))) checkErr(err) preinput := &tos.PreSignedURLInput{ enum.HttpMethodPut, "wanyix-1",// 桶名 "mul-lab-test",// 对象名 3600,// 过期时间 map[string]string{}, map[string]string{"partNumber": "1", "uploadId": "7443ad5cb011dd73cfd501db44a3ff10"},// 各个分片数字及分片ID,uploadId 始终一致,partNumber 跟分片数量一致,如第一个分片,为1 "", } get, err := client.PreSignedURL(preinput) fmt.Println(get.SignedUrl) }
响应如下:
https://wanyix-1.tos-cn-beijing.volces.com/mul-lab-test?X-Tos-Algorithm=TOS4-HMAC-SHA256&X-Tos-Credential=AKLTN2QyZmNlZjE0NjM2NDUwOdslMDdmYTllZmJkOGFjYTU%2F20230815%2Fcn-beijing%2Ftos%2Frequest&X-Tos-Date=20230815T081810Z&X-Tos-Expires=3600&X-Tos-Signature=c949c66d5250ce1006ae4750902408814d57c664293dd642285caccc8ea34098&X-Tos-SignedHeaders=host&partNumber=2&uploadId=7443ad5cb011dd73cfd501db44a3ff10
使用PUT 方法,url 填入步骤三中预签名 URL,Body 处将要上传对象的分片导入。
结果如下:
上传完成后,将每个分片的ETag 进行保存。
package main import ( "context" "fmt" "github.com/volcengine/ve-tos-golang-sdk/v2/tos" ) func checkErr(err error) { if err != nil { if serverErr, ok := err.(*tos.TosServerError); ok { fmt.Println("Error:", serverErr.Error()) fmt.Println("Request ID:", serverErr.RequestID) fmt.Println("Response Status Code:", serverErr.StatusCode) fmt.Println("Response Header:", serverErr.Header) fmt.Println("Response Err Code:", serverErr.Code) fmt.Println("Response Err Msg:", serverErr.Message) } else if clientErr, ok := err.(*tos.TosClientError); ok { fmt.Println("Error:", clientErr.Error()) fmt.Println("Client Cause Err:", clientErr.Cause.Error()) } else { fmt.Println("Error:", err) } panic(err) } } func main() { var ( accessKey = "真实AK" secretKey = "真实SK" endpoint = "tos-cn-beijing.volces.com" region = "cn-beijing" // 填写 BucketName bucketName = "wanyix-1" // 指定的 ObjectKey objectKey = "mul-lab-test" ctx = context.Background() ) // 初始化客户端 client, err := tos.NewClientV2(endpoint, tos.WithRegion(region), tos.WithCredentials(tos.NewStaticCredentials(accessKey, secretKey))) checkErr(err) var parts []tos.UploadedPartV2 parts = append(parts, tos.UploadedPartV2{PartNumber: 1, ETag: "141ab4936c1084e1d4edca2192a1d1ff"}) parts = append(parts, tos.UploadedPartV2{PartNumber: 2, ETag: "141ab4936c1084e1d4edca2192a1d1ff"}) completeOutput, err := client.CompleteMultipartUploadV2(ctx, &tos.CompleteMultipartUploadV2Input{ Bucket: bucketName, Key: objectKey, UploadID: "7443ad5cb011dd73cfd501db33a3ff10", Parts: parts, }) checkErr(err) fmt.Println("CompleteMultipartUploadV2 Request ID:", completeOutput.RequestID) }
响应如下:
CompleteMultipartUploadV2 Request ID: acd301db3897047164db3897-b55924b-1qVpVX-CoMU-cb-tos-front-azb-1
控制台进行验证:
上传完成。
参考文档:
[1] TOS Go SDK
[2] 分片上传
如果您有其他问题,欢迎您联系火山引擎技术支持服务