Updated on 2024-06-21 GMT+08:00

Multipart Upload Overview (SDK for Go)

You can upload large files using multipart upload. Multipart upload is applicable to many scenarios, including:

  • Files to be uploaded are larger than 100 MB.
  • The network condition is poor. Connection to the OBS server is constantly down.
  • Sizes of files to be uploaded are uncertain.

A multipart upload consists of the following steps:

  1. Initiate a multipart upload (ObsClient.InitiateMultipartUpload).
  2. Upload parts one by one or concurrently (ObsClient.UploadPart).
  3. Assemble parts (ObsClient.CompleteMultipartUpload) or abort the multipart upload (ObsClient.AbortMultipartUpload).

The following code shows how to perform a multipart upload:
  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 a dependency.
import (
    "fmt"
    obs "github.com/huaweicloud/huaweicloud-sdk-go-obs/obs"
)

//Obtain an AK/SK pair using environment variables or import the AK/SK pair in other ways. Using hard coding may result in leakage.
//Obtain an AK/SK pair on the management console. For details, see https://support.huaweicloud.com/eu/usermanual-ca/ca_01_0003.html.
ak := os.Getenv("AccessKeyID")
sk := os.Getenv("SecretAccessKey")
// (Optional) If you use a temporary AK/SK pair and a security token to access OBS, you are advised not to use hard coding to reduce leakage risks. You can obtain an AK/SK pair using environment variables or import it in other ways.
// securityToken := os.Getenv("SecurityToken")
// Enter the endpoint corresponding to the bucket. EU-Dublin is used here as an example. Replace it with the one currently in use.
endPoint := "https://obs.eu-west-101.myhuaweicloud.com"
// Create an obsClient instance.
// If you use a temporary AK/SK pair and a security token to access OBS, use the obs.WithSecurityToken method to specify a security token when creating an instance.
obsClient, _:= obs.New(ak, sk, endPoint/*, obs.WithSecurityToken(securityToken)*/)

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

       // Initiate a multipart upload.
       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)
              }
       }

       // Upload a part.
       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)
              }
       }

       // Assemble parts.
       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)
              }
       }
}

Below lists other multipart upload operations: