分段复制
更新时间: 2019-03-14 10:05
分段复制是分段上传的一种特殊情况,即分段上传任务中的段通过复制OBS指定桶中现有对象(或对象的一部分)来实现。您可以通过ObsClient.CopyPart来复制段。以下代码展示了如何使用分段复制模式复制大对象:
- // 引入依赖包
- import (
- "fmt"
- "obs"
- )
- var ak = "*** Provide your Access Key ***"
- var sk = "*** Provide your Secret Key ***"
- var endpoint = "https://your-endpoint"
- var destBucketName = "bucketname"
- var destObjectKey = "objectkey"
- var sourceBucketName = "sourcebucketname"
- var sourceObjectKey = "sourceobjectkey"
- // 创建ObsClient结构体
- var obsClient, _ = obs.New(ak, sk, endpoint)
- func main() {
- // 初始化分段上传任务
- input := &obs.InitiateMultipartUploadInput{}
- input.Bucket = destBucketName
- input.Key = destObjectKey
- output, err := obsClient.InitiateMultipartUpload(input)
- if err != nil {
- panic(err)
- }
- uploadId := output.UploadId
- fmt.Printf("UploadId:%s\n", uploadId)
- fmt.Println()
- // 每段复制100MB
- var partSize int64 = 100 * 1024 * 1024
- // 获取大对象信息
- getObjectMetadataInput := &obs.GetObjectMetadataInput{}
- getObjectMetadataInput.Bucket = sourceBucketName
- getObjectMetadataInput.Key = sourceObjectKey
- getObjectMetadataOutput, err := obsClient.GetObjectMetadata(getObjectMetadataInput)
- if err != nil {
- panic(err)
- }
- objectSize := getObjectMetadataOutput.ContentLength
- // 计算需要复制的段数
- partCount := int(objectSize / partSize)
- if objectSize%partSize != 0 {
- partCount++
- }
- // 执行并发复制段
- partChan := make(chan obs.Part, 5)
- for i := 0; i < partCount; i++ {
- partNumber := i + 1
- rangeStart := int64(i) * partSize
- rangeEnd := rangeStart + partSize - 1
- if i+1 == partCount {
- rangeEnd = objectSize - 1
- }
- go func() {
- copyPartInput := &obs.CopyPartInput{}
- copyPartInput.Bucket = destBucketName
- copyPartInput.Key = destObjectKey
- copyPartInput.UploadId = uploadId
- // 分段号
- copyPartInput.PartNumber = int(partNumber)
- copyPartInput.CopySourceBucket = sourceBucketName
- copyPartInput.CopySourceKey = sourceObjectKey
- // 复制段起始位置
- copyPartInput.CopySourceRangeStart = rangeStart
- // 复制段结束位置
- copyPartInput.CopySourceRangeEnd = rangeEnd
- copyPartOutput, err := obsClient.CopyPart(copyPartInput)
- if err == nil {
- fmt.Printf("%d finished\n", partNumber)
- partChan <- obs.Part{ETag: copyPartOutput.ETag, PartNumber: copyPartOutput.PartNumber}
- } else {
- panic(err)
- }
- }()
- }
- parts := make([]obs.Part, 0, partCount)
- // 等待复制完成
- for {
- part, ok := <-partChan
- if !ok {
- break
- }
- parts = append(parts, part)
- if len(parts) == partCount {
- close(partChan)
- }
- }
- completeMultipartUploadInput := &obs.CompleteMultipartUploadInput{}
- completeMultipartUploadInput.Bucket = destBucketName
- completeMultipartUploadInput.Key = destObjectKey
- completeMultipartUploadInput.UploadId = uploadId
- completeMultipartUploadInput.Parts = parts
- // 合并段
- completeMultipartUploadOutput, err := obsClient.CompleteMultipartUpload(completeMultipartUploadInput)
- if err != nil {
- panic(err)
- }
- fmt.Printf("RequestId:%s\n", completeMultipartUploadOutput.RequestId)
- }
父主题:上传对象