
# 分段相关接口说明(Go SDK)
对于较大文件上传，可以切分成段上传。用户可以在如下的应用场景内（但不仅限于此），使用分段上传的模式：
- 上传超过100MB大小的文件。
- 网络条件较差，和OBS服务端之间的链接经常断开。
- 上传前无法确定将要上传文件的大小。
分段上传分为如下3个步骤：
1. [初始化分段上传任务](https://support.huaweicloud.com/sdk-go-devg-obs/obs_33_0511.html)（ObsClient.InitiateMultipartUpload）。
2. [逐个或并行上传段](https://support.huaweicloud.com/sdk-go-devg-obs/obs_33_0512.html)（ObsClient.UploadPart）。
3. [合并段](https://support.huaweicloud.com/sdk-go-devg-obs/obs_33_0515.html)（ObsClient.CompleteMultipartUpload）或[取消分段上传任务](https://support.huaweicloud.com/sdk-go-devg-obs/obs_33_0516.html)(ObsClient.AbortMultipartUpload)。
以下代码简单展示了分段上传的各个步骤：
```
package main
// 引入依赖包
import (
    "fmt"
    "os"
    obs "github.com/huaweicloud/huaweicloud-sdk-go-obs/obs"
)
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.cn-north-4.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)
        }
    }
}
```
其他分段操作请参考：
- [分段上传-列举分段上传任务](https://support.huaweicloud.com/sdk-go-devg-obs/obs_33_0408.html)
- [分段上传-列举已上传的段](https://support.huaweicloud.com/sdk-go-devg-obs/obs_33_0514.html)
- [分段上传-复制段](https://support.huaweicloud.com/sdk-go-devg-obs/obs_33_0513.html)
 
