更新时间:2026-08-14 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
package main
// 引入依赖包
import (
    "fmt"
    "os"
)
func main() {
    // 推荐通过环境变量获取AKSK,这里也可以使用其他外部引入方式传入,如果使用硬编码可能会存在泄露风险。
    // 您可以登录访问管理控制台获取访问密钥AK/SK。
    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)*/)
    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)
        }
    }
}

其他分段操作请参考: