更新时间:2024-06-21 GMT+08:00

分段相关接口说明(Go SDK)

对于较大文件上传,可以切分成段上传。用户可以在如下的应用场景内(但不仅限于此),使用分段上传的模式:

  • 上传超过100MB大小的文件。
  • 网络条件较差,和OBS服务端之间的链接经常断开。
  • 上传前无法确定将要上传文件的大小。

分段上传分为如下3个步骤:

  1. 初始化分段上传任务(ObsClient.InitiateMultipartUpload)。
  2. 逐个或并行上传段(ObsClient.UploadPart)。
  3. 合并段(ObsClient.CompleteMultipartUpload)或取消分段上传任务(ObsClient.AbortMultipartUpload)。

以下代码简单展示了分段上传的各个步骤:
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
// 引入依赖包
import (
    "fmt"
    obs "github.com/huaweicloud/huaweicloud-sdk-go-obs/obs"
)

//推荐通过环境变量获取AKSK,这里也可以使用其他外部引入方式传入,如果使用硬编码可能会存在泄露风险。
//您可以登录访问管理控制台获取访问密钥AK/SK,获取方式请参见https://support.huaweicloud.com/intl/zh-cn/usermanual-ca/ca_01_0003.html。
ak := os.Getenv("AccessKeyID")
sk := os.Getenv("SecretAccessKey")
// 【可选】如果使用临时AK/SK和SecurityToken访问OBS,同样建议您尽量避免使用硬编码,以降低信息泄露风险。您可以通过环境变量获取访问密钥AK/SK,也可以使用其他外部引入方式传入。
// securityToken := os.Getenv("SecurityToken")
// endpoint填写Bucket对应的Endpoint, 这里以中国-香港为例,其他地区请按实际情况填写。
endPoint := "https://obs.ap-southeast-1.myhuaweicloud.com"
// 创建obsClient实例
// 如果使用临时AKSK和SecurityToken访问OBS,需要在创建实例时通过obs.WithSecurityToken方法指定securityToken值。
obsClient, _:= obs.New(ak, sk, endPoint/*, obs.WithSecurityToken(securityToken)*/)

func main() {
       var uploadId = ""
       var eTag1 = ""
       var eTag2 = ""
       var partNumber1= 1
       var partNumber2= 2

       // 初始化分段上传任务
       inputInit := &obs.InitiateMultipartUploadInput{}
       inputInit.Bucket = "bucketname"
       inputInit.Key = "objectkey"
       outputInit, err := obsClient.InitiateMultipartUpload(inputInit)
       if err == nil {
              fmt.Printf("RequestId:%s\n", outputInit.RequestId)
              fmt.Printf("UploadId:%s\n", outputInit.UploadId)
              uploadId = outputInit.UploadId
       } else {
              if obsError, ok := err.(obs.ObsError); ok {
                     fmt.Println(obsError.Code)
                     fmt.Println(obsError.Message)
              } else {
                     fmt.Println(err)
              }
       }

       // 上传段
       inputUploadPart := &obs.UploadPartInput{}
       inputUploadPart.Bucket = "bucketname"
       inputUploadPart.Key = "objectkey"
       inputUploadPart.UploadId = uploadId
       inputUploadPart.PartNumber = partNumber1
       inputUploadPart.SourceFile = "localFilePath"
       outputUploadPart, err := obsClient.UploadPart(inputUploadPart)
       if err == nil {
              fmt.Printf("RequestId:%s\n", outputUploadPart.RequestId)
              fmt.Printf("ETag:%s\n", outputUploadPart.ETag)
              eTag1 = outputUploadPart.ETag
       } else {
              if obsError, ok := err.(obs.ObsError); ok {
                     fmt.Println(obsError.Code)
                     fmt.Println(obsError.Message)
              } else {
                     fmt.Println(err)
              }
       }
       inputUploadPart = &obs.UploadPartInput{}
       inputUploadPart.Bucket = "bucketname"
       inputUploadPart.Key = "objectkey"
       inputUploadPart.UploadId = uploadId
       inputUploadPart.PartNumber = partNumber2
       inputUploadPart.SourceFile = "localFilePath"
       outputUploadPart, err = obsClient.UploadPart(inputUploadPart)
       if err == nil {
              fmt.Printf("RequestId:%s\n", outputUploadPart.RequestId)
              fmt.Printf("ETag:%s\n", outputUploadPart.ETag)
              eTag2 = outputUploadPart.ETag
       } else {
              if obsError, ok := err.(obs.ObsError); ok {
                     fmt.Println(obsError.Code)
                     fmt.Println(obsError.Message)
              } else {
                     fmt.Println(err)
              }
       }

       // 合并段
       inputCompleteMultipart := &obs.CompleteMultipartUploadInput{}
       inputCompleteMultipart.Bucket = "bucketname"
       inputCompleteMultipart.Key = "objectkey"
       inputCompleteMultipart.UploadId = uploadId
       inputCompleteMultipart.Parts = []obs.Part{
              obs.Part{PartNumber: partNumber1, ETag: eTag1},
              obs.Part{PartNumber: partNumber2, ETag: eTag2},
       }
       outputCompleteMultipart, err := obsClient.CompleteMultipartUpload(inputCompleteMultipart)
       if err == nil {
              fmt.Printf("RequestId:%s\n", outputCompleteMultipart.RequestId)
              fmt.Printf("Location:%s, Bucket:%s, Key:%s, ETag:%s\n", outputCompleteMultipart.Location, outputCompleteMultipart.Bucket, outputCompleteMultipart.Key, outputCompleteMultipart.ETag)
       } else {
              if obsError, ok := err.(obs.ObsError); ok {
                     fmt.Println(obsError.Code)
                     fmt.Println(obsError.Message)
              } else {
                     fmt.Println(err)
              }
       }
}

其他分段操作请参考: