Alibaba Cloud Object Storage Service (OSS) provides multipart upload so that you can split a large object into multiple parts and upload the parts separately. After the parts are uploaded, you can call the CompleteMultipartUpload operation to combine these parts into an object.

Prerequisites

A bucket is created. For more information, see Create buckets.

Scenarios

  • Accelerated upload of large objects

    If you want to upload a file larger than 5 GB in size, you can use multipart upload to split the file into multiple parts and concurrently upload the parts to accelerate the upload.

  • Unstable network environments

    We recommend that you use multipart upload when network conditions are unstable. If specific parts fail to be uploaded, you need only to upload these parts.

  • Uncertain object size

    If you are uncertain of the size of uploaded objects, you can use multipart upload. This case is common in industrial applications such as video surveillance.

Multipart upload process

The following flowchart shows the basic process of multipart upload.

The preceding process consists of the following steps:

  1. Split the uploaded object into parts based on a specific size.
  2. Call the InitiateMultipartUpload operation to initiate a multipart upload task.
  3. Call the UploadPart operation to upload the parts.
    After the object is split into parts, partNumber is specified for each part to indicate the sequence of the parts. Therefore, you can concurrently upload the parts. More concurrent uploads do not necessarily result in faster upload speeds. Therefore, we recommend that you specify the number of concurrent uploads based on your network conditions and the workload of your devices.

    To cancel a multipart upload task, you can call the AbortMultipartUpload operation. After the multipart upload task is canceled, parts that are uploaded by the task are also deleted.

  4. Call the CompleteMultipartUpload operation to combine the uploaded parts into an object.

Limits

Item Limit
Object size Multipart upload supports objects up to 48.8 TB in size.
Number of parts You can set the number of parts to a value that ranges from 1 to 10000.
Part size Each part can be 100 KB to 5 GB in size. The size of the last part is not limited.
Maximum number of parts that can be returned for a single ListParts request Up to 1,000 parts can be returned for a single ListParts request.
Maximum number of multipart upload tasks that can be returned for a single ListMultipartUploads request Up to 1,000 parts can be returned for a single ListMultipartUploads request.

Usage notes

  • Optimize object upload performance

    If you upload a large number of objects with sequential prefixes such as timestamps and letters in the object names, many object indexes may be stored in a single partition. If a large number of requests are sent to query these objects, the latency increases. We recommend that you do not upload a large number of objects with sequential prefixes in their names. For more information, see OSS performance and scalability best practices.

  • Overwrite objects

    If you upload an object whose name is the same as an existing object in OSS, the existing object is overwritten by the uploaded object. You can use the following methods to prevent objects from being unexpectedly overwritten:

    • Enable versioning

      When versioning is enabled for a bucket, overwritten objects are saved as previous versions. You can restore an object to a previous version at any time. For more information, see Overview.

    • Include a specific parameter in the upload request

      Include the x-oss-forbid-overwrite parameter in the upload request header and set the parameter to true. This way, if you upload an object whose name is the same as an existing object, the upload fails and OSS returns the FileAlreadyExists error. For more information, see InitiateMultipartUpload.

  • Delete parts
    When a multipart upload task is interrupted, parts that are uploaded by the task are stored in the specified bucket. To prevent additional storage fees, we recommend that you use the following methods to delete these parts if you no longer need these parts:

Use OSS SDKs

The following code provides examples on how to perform multipart upload by using OSS SDKs for common programming languages. For more information about how to perform multipart upload by using OSS SDKs for other programming languages, see Overview.

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

public class Demo {

    public static void main(String[] args) throws Exception {
        // In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // Security risks may arise if you use the AccessKey pair of an Alibaba Cloud account to access OSS because the account has permissions on all API operations. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
        String accessKeyId = "yourAccessKeyId";
        String accessKeySecret = "yourAccessKeySecret";
        // Specify the name of the bucket. Example: examplebucket. 
        String bucketName = "examplebucket";
        // Specify the full path of the object. Example: exampledir/exampleobject.txt. The full path of the object cannot contain the bucket name. 
        String objectName = "exampledir/exampleobject.txt";

        // Create an OSSClient instance. 
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        try {
            // Create an InitiateMultipartUploadRequest object. 
            InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, objectName);

            // The following code provides an example on how to specify the request headers when you initiate a multipart upload task. 
            // ObjectMetadata metadata = new ObjectMetadata();
            // metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
            // Specify the caching behavior of the web page for the object. 
            // metadata.setCacheControl("no-cache");
            // Specify the name of the object when the object is downloaded. 
            // metadata.setContentDisposition("attachment;filename=oss_MultipartUpload.txt");
            // Specify the encoding format for the content of the object. 
            // metadata.setContentEncoding(OSSConstants.DEFAULT_CHARSET_NAME);
            // Specify whether existing objects are overwritten by objects with the same names when the multipart upload task is initiated. In this example, this parameter is set to true, which indicates that the object with the same name cannot be overwritten. 
            // metadata.setHeader("x-oss-forbid-overwrite", "true");
            // Specify the server-side encryption method that is used to encrypt each part of the object to upload. 
            // metadata.setHeader(OSSHeaders.OSS_SERVER_SIDE_ENCRYPTION, ObjectMetadata.KMS_SERVER_SIDE_ENCRYPTION);
            // Specify the encryption algorithm that is used to encrypt the object. If you do not configure this parameter, objects are encrypted by using AES-256. 
            // metadata.setHeader(OSSHeaders.OSS_SERVER_SIDE_DATA_ENCRYPTION, ObjectMetadata.KMS_SERVER_SIDE_ENCRYPTION);
            // Specify the ID of the customer master key (CMK) that is managed by Key Management Service (KMS). 
            // metadata.setHeader(OSSHeaders.OSS_SERVER_SIDE_ENCRYPTION_KEY_ID, "9468da86-3509-4f8d-a61e-6eab1eac****");
            // Specify the storage class of the object. 
            // metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard);
            // Configure tagging for the object. You can specify multiple tags for the object at the same time. 
            // metadata.setHeader(OSSHeaders.OSS_TAGGING, "a:1");
            // request.setObjectMetadata(metadata);

            // Initiate a multipart copy task. 
            InitiateMultipartUploadResult upresult = ossClient.initiateMultipartUpload(request);
            // Obtain the upload ID, which uniquely identifies the multipart upload task. You can use the upload ID to cancel or query the multipart upload task. 
            String uploadId = upresult.getUploadId();

            // partETags is the set of PartETags. A PartETag consists of the part number and ETag of an uploaded part 
            List<PartETag> partETags =  new ArrayList<PartETag>();
            // The size of each part, which is used to calculate the number of parts of the object. Unit: bytes. 
            final long partSize = 1 * 1024 * 1024L;   // Set the part size to 1 MB. 

            // Specify the full path of the local file that you want to upload. By default, if you do not specify the full path of the local file, the local file is uploaded from the path of the project to which the sample program belongs. 
            final File sampleFile = new File("D:\\localpath\\examplefile.txt");
            long fileLength = sampleFile.length();
            int partCount = (int) (fileLength / partSize);
            if (fileLength % partSize != 0) {
                partCount++;
            }
            // Upload each part until all parts are uploaded. 
            for (int i = 0; i < partCount; i++) {
                long startPos = i * partSize;
                long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize;
                InputStream instream = new FileInputStream(sampleFile);
                // Skip the parts that have been uploaded. 
                instream.skip(startPos);
                UploadPartRequest uploadPartRequest = new UploadPartRequest();
                uploadPartRequest.setBucketName(bucketName);
                uploadPartRequest.setKey(objectName);
                uploadPartRequest.setUploadId(uploadId);
                uploadPartRequest.setInputStream(instream);
                // Configure the size available for each part. Each part except for the last part must be larger than 100 KB in size. 
                uploadPartRequest.setPartSize(curPartSize);
                // Set part numbers. Each part has a part number. The number ranges from 1 to 10000. If the specified number is beyond the range, OSS returns an InvalidArgument error code. 
                uploadPartRequest.setPartNumber( i + 1);
                // Parts are not necessarily uploaded in sequence. They can be uploaded from different OSS clients. OSS sorts the parts based on their part numbers and combines them into a complete object. 
                UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
                // Each time a part is uploaded, OSS returns a result that contains a PartETag. The PartETags are stored in partETags. 
                partETags.add(uploadPartResult.getPartETag());
            }


            // Create a CompleteMultipartUploadRequest object. 
            // When the multipart upload task is completed, you must provide all valid PartETags. After receiving the PartETags, OSS verifies the validity of all parts one by one. After all parts are verified, OSS combines these parts into a complete object. 
            CompleteMultipartUploadRequest completeMultipartUploadRequest =
                    new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags);

            // Optional. The following code provides an example on how to set the access control list (ACL) of the object. 
            // completeMultipartUploadRequest.setObjectACL(CannedAccessControlList.Private);
            // Specifies whether to list all parts that are uploaded by using the current upload ID. If you want to combine the parts by listing the parts in the server side, you have the option to leave partETags contained in CompleteMultipartUploadRequest empty. 
            // Map<String, String> headers = new HashMap<String, String>();
            // If x-oss-complete-all:yes is specified in the request, OSS lists all parts that are uploaded by using the current upload ID, sorts the parts by part number, and then performs the CompleteMultipartUpload operation. 
            // If you configure x-oss-complete-all:yes in the request, the request body cannot be specified. Otherwise, an error occurs. 
            // headers.put("x-oss-complete-all","yes");
            // completeMultipartUploadRequest.setHeaders(headers);

            // Complete the multipart upload task. 
            CompleteMultipartUploadResult completeMultipartUploadResult = ossClient.completeMultipartUpload(completeMultipartUploadRequest);
            System.out.println(completeMultipartUploadResult.getETag());
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}            
<? php
if (is_file(__DIR__ . '/../autoload.php')) {
    require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
    require_once __DIR__ . '/../vendor/autoload.php';
}

use OSS\OssClient;
use OSS\Core\OssException;
use OSS\Core\OssUtil;

// Security risks may arise if you use the AccessKey pair of an Alibaba Cloud account to log on to OSS because the account has permissions on all API operations. We recommend that you use your RAM user's credentials to call API operations or perform routine operations and maintenance. To create a RAM user, log on to the RAM console.
$accessKeyId = "<yourAccessKeyId>";
$accessKeySecret = "<yourAccessKeySecret>";
// The endpoint of the China (Hangzhou) region is used in this example. Specify the actual endpoint.
$endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
$bucket= "<yourBucketName>";
$object = "<yourObjectName>";
$uploadFile = "<yourLocalFile>";

/**
 * Step 1: Initiate a multipart upload task and obtain the upload ID.
 */
try{
    $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);

    // Obtain the upload ID. The upload ID is the unique identifier for a multipart upload task. You can initiate related operations such as cancel or query a multipart upload task based on the upload ID.
    $uploadId = $ossClient->initiateMultipartUpload($bucket, $object);
} catch(OssException $e) {
    printf(__FUNCTION__ . ": initiateMultipartUpload FAILED\n");
    printf($e->getMessage() . "\n");
    return;
}
print(__FUNCTION__ . ": initiateMultipartUpload OK" . "\n");
/*
 * Step 2: Upload the parts.
 */
$partSize = 10 * 1024 * 1024;
$uploadFileSize = sprintf('%u',filesize($uploadFile));
$pieces = $ossClient->generateMultiuploadParts($uploadFileSize, $partSize);
$responseUploadPart = array();
$uploadPosition = 0;
$isCheckMd5 = true;
foreach ($pieces as $i => $piece) {
    $fromPos = $uploadPosition + (integer)$piece[$ossClient::OSS_SEEK_TO];
    $toPos = (integer)$piece[$ossClient::OSS_LENGTH] + $fromPos - 1;
    $upOptions = array(
        // Specify the local file you want to upload.
        $ossClient::OSS_FILE_UPLOAD => $uploadFile,
        // Configure part numbers.
        $ossClient::OSS_PART_NUM => ($i + 1),
        // Specify the position from which to start multipart upload.
        $ossClient::OSS_SEEK_TO => $fromPos,
        // Specify the object size.
        $ossClient::OSS_LENGTH => $toPos - $fromPos + 1,
        // Specify whether to enable MD5 verification. A value of true indicates that the MD5 verification is enabled.
        $ossClient::OSS_CHECK_MD5 => $isCheckMd5,
    );
    // Enable MD5 verification.
    if ($isCheckMd5) {
        $contentMd5 = OssUtil::getMd5SumForFile($uploadFile, $fromPos, $toPos);
        $upOptions[$ossClient::OSS_CONTENT_MD5] = $contentMd5;
    }
    try {
        // Upload the parts.
        $responseUploadPart[] = $ossClient->uploadPart($bucket, $object, $uploadId, $upOptions);
    } catch(OssException $e) {
        printf(__FUNCTION__ . ": initiateMultipartUpload, uploadPart - part#{$i} FAILED\n");
        printf($e->getMessage() . "\n");
        return;
    }
    printf(__FUNCTION__ . ": initiateMultipartUpload, uploadPart - part#{$i} OK\n");
}
// $uploadParts is an array that consists of the ETags and the PartNumbers of each part.
$uploadParts = array();
foreach ($responseUploadPart as $i => $eTag) {
    $uploadParts[] = array(
        'PartNumber' => ($i + 1),
        'ETag' => $eTag,
    );
}
/**
 * Step 3: Complete the upload.
 */
try {
    // All valid $uploadParts are required for the completeMultipartUpload operation. OSS verifies the validity of each part after OSS receives the submitted $uploadParts. After all parts are validated, OSS combines these parts into a complete object.
    $ossClient->completeMultipartUpload($bucket, $object, $uploadId, $uploadParts);
}  catch(OssException $e) {
    printf(__FUNCTION__ . ": completeMultipartUpload FAILED\n");
    printf($e->getMessage() . "\n");
    return;
}
printf(__FUNCTION__ . ": completeMultipartUpload OK\n");
            
const OSS = require('ali-oss');
const path = require("path");

const client = new OSS({
  // Specify the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the region to oss-cn-hangzhou. 
  region: 'yourRegion',
  // The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
  accessKeyId: 'yourAccessKeyId',
  accessKeySecret: 'yourAccessKeySecret',
  // Specify the bucket name. Example: examplebucket. 
  bucket: 'examplebucket',
});


const progress = (p, _checkpoint) => {
  // Record the upload progress of the object. 
  console.log(p); 
  // Record the checkpoint information about the multipart upload task. 
  console.log(_checkpoint); 
};

const headers = {
  // Specify the caching behavior of the web page when the object is downloaded. 
  'Cache-Control': 'no-cache',
  // Specify the name of the object when the object is downloaded. 
  'Content-Disposition': 'example.txt',
  // Specify the content encoding format of the object when the object is downloaded. 
  'Content-Encoding': 'utf-8', 
  // Specify the validity period of the request. Unit: milliseconds. 
  'Expires': '1000',
  // Specify the storage class of the object. 
  'x-oss-storage-class': 'Standard', 
  // Specify tags for the object. You can specify multiple tags for the object at the same time. 
  'x-oss-tagging': 'Tag1=1&Tag2=2', 
  // Specify whether to overwrite existing objects with the same names as the objects to upload when the multipart upload task is initialized. In this example, this parameter is set to true, which indicates that existing objects cannot be overwritten by objects with the same names. 
  'x-oss-forbid-overwrite': 'true'
}

// Start the multipart upload task. 
async function multipartUpload() {
  try {
    // Specify the full path of the object. Example: exampledir/exampleobject.txt. Then, specify the full path of the local file. Example: D:\\localpath\\examplefile.txt. The full path of the object cannot contain the bucket name. 
    // By default, if you set this parameter to the name of a local file such as examplefile.txt without specifying the local path, the local file is uploaded from the local path of the project to which the sample program belongs. 
    const result = await client.multipartUpload('exampledir/exampleobject.txt', path.normalize('D:\\localpath\\examplefile.txt'), {
      progress,
      // headers,
      // Configure the meta parameter to specify metadata for the object. You can call the HeadObject operation to query the object metadata. 
      meta: {
        year: 2020,
        people: 'test',
      },
    });
    console.log(result);
    // Specify the full path of the object. Example: exampledir/exampleobject.txt. The full path of the object cannot contain the bucket name. 
    const head = await client.head('exampledir/exampleobject.txt');
    console.log(head);
  } catch (e) {
    // Handle timeout exceptions. 
    if (e.code === 'ConnectionTimeoutError') {
      console.log('TimeoutError');
      // do ConnectionTimeoutError operation
    }
    console.log(e);
  }
}

multipartUpload();
# -*- coding: utf-8 -*-
import os
from oss2 import SizedFileAdapter, determine_part_size
from oss2.models import PartInfo
import oss2

# Security risks may arise if you use the AccessKey pair of an Alibaba Cloud account to access OSS because the account has permissions on all API operations. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
auth = oss2.Auth('yourAccessKeyId', 'yourAccessKeySecret')
# In this example, the endpoint of the China (Hangzhou) region is used. Specify the endpoint based on your business requirements. 
# Specify the name of the bucket. Example: examplebucket. 
bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'examplebucket')
# Specify the full path of the object. The full path cannot contain the bucket name. Example: exampledir/exampleobject.txt. 
key = 'exampledir/exampleobject.txt'
# Specify the full path of the local file that you want to upload. Example: D:\\localpath\\examplefile.txt. 
filename = 'D:\\localpath\\examplefile.txt'

total_size = os.path.getsize(filename)
# Use the determine_part_size method to determine the size of each part. 
part_size = determine_part_size(total_size, preferred_size=100 * 1024)

# Initiate a multipart upload task. 
# If you want to specify the storage class of the object when you initiate the multipart upload task, configure the related headers when you call the init_multipart_upload method. 
# headers = dict()
# Specify the caching behavior of the web page for the object. 
# headers['Cache-Control'] = 'no-cache'
# Specify the name of the object when it is downloaded. 
# headers['Content-Disposition'] = 'oss_MultipartUpload.txt'
# Specify the encoding format for the content of the object. 
# headers['Content-Encoding'] = 'utf-8'
# Specify the validity period. Unit: milliseconds. 
# headers['Expires'] = '1000'
# Specify whether to overwrite the existing object with the same name as the uploaded object when you initiate the multipart upload task. In this example, this parameter is set to true, which indicates that the existing object with the same name cannot be overwritten by the uploaded object. 
# headers['x-oss-forbid-overwrite'] = 'true'
# Specify the server-side encryption method that is used to encrypt each part of the object that you want to upload. 
# headers[OSS_SERVER_SIDE_ENCRYPTION] = SERVER_SIDE_ENCRYPTION_KMS
# Specify the algorithm that is used to encrypt the object. If you do not configure this parameter, objects are encrypted by using AES-256. 
# headers[OSS_SERVER_SIDE_DATA_ENCRYPTION] = SERVER_SIDE_ENCRYPTION_KMS
# Specify the ID of the Customer Master Key (CMK) that is managed by Key Management Service (KMS). 
# headers[OSS_SERVER_SIDE_ENCRYPTION_KEY_ID] = '9468da86-3509-4f8d-a61e-6eab1eac****'
# Specify the storage class of the object. 
# headers['x-oss-storage-class'] = oss2.BUCKET_STORAGE_CLASS_STANDARD
# Specify tags for the object. You can specify multiple tags for the object at the same time. 
# headers[OSS_OBJECT_TAGGING] = 'k1=v1&k2=v2&k3=v3'
# upload_id = bucket.init_multipart_upload(key, headers=headers).upload_id
upload_id = bucket.init_multipart_upload(key).upload_id
parts = []

# Upload the parts one by one. 
with open(filename, 'rb') as fileobj:
    part_number = 1
    offset = 0
    while offset < total_size:
        num_to_upload = min(part_size, total_size - offset)
        # Call the SizedFileAdapter(fileobj, size) method to generate a new object and recalculate the length of the append object. 
        result = bucket.upload_part(key, upload_id, part_number,
                                    SizedFileAdapter(fileobj, num_to_upload))
        parts.append(PartInfo(part_number, result.etag))

        offset += num_to_upload
        part_number += 1

# Complete the multipart upload task. 
# The following code provides an example on how to configure headers when you complete the multipart upload task: 
headers = dict()
# Specify the access control list (ACL) of the object. In this example, this parameter is set to OBJECT_ACL_PRIVATE, which indicates private. 
# headers["x-oss-object-acl"] = oss2.OBJECT_ACL_PRIVATE
# If you configure x-oss-complete-all:yes in the request, OSS lists all parts that are uploaded by using the current upload ID, sorts the parts by part number, and then performs the CompleteMultipartUpload operation. 
# If you configure x-oss-complete-all:yes in the request, the request body cannot be specified. Otherwise, an error occurs. 
headers["x-oss-complete-all"] = 'yes'
bucket.complete_multipart_upload(key, upload_id, parts, headers=headers)
# bucket.complete_multipart_upload(key, upload_id, parts)

# Verify the result of the multipart upload task. 
with open(filename, 'rb') as fileobj:
    assert bucket.get_object(key).read() == fileobj.read()            
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
  </head>

  <body>
    <button id="submit">Upload An Object</button>
    <input id="file" type="file" />
    <!-- import an SDK file -->
    <script
      type="text/javascript"
      src="https://gosspublic.alicdn.com/aliyun-oss-sdk-6.16.0.min.js"
    ></script>
    <script type="text/javascript">
      const client = new OSS({
        // Set yourRegion to the region in which the bucket is located. For example, if your bucket is located in the China (Hangzhou) region, set yourRegion to oss-cn-hangzhou. 
        region: "yourRegion",
        // Specify the temporary AccessKey pair obtained from STS. 
        accessKeyId: "yourAccessKeyId",
        accessKeySecret: "yourAccessKeySecret",
        // Specify the security token obtained from STS. 
        stsToken: "yourSecurityToken",
        // Specify the name of the bucket. Example: examplebucket. 
        bucket: "examplebucket",
      });

      const headers = {
        // Specify the caching behavior of the web page when the object is downloaded. 
        "Cache-Control": "no-cache",
        // Specify the name of the object when the object is downloaded. 
        "Content-Disposition": "example.txt",
        // Specify the content encoding format of the object when the object is downloaded. 
        "Content-Encoding": "utf-8",
        // Specify the validity period of the request. Unit: milliseconds. 
        Expires: "1000",
        // Specify the storage class of the object. 
        "x-oss-storage-class": "Standard",
        // Specify the tag for the object. You can specify multiple tags for the object at the same time. 
        "x-oss-tagging": "Tag1=1&Tag2=2",
        // Specify whether existing objects are overwritten by objects with the same names when the multipart upload task is initiated. In this example, this parameter is set to true, which indicates that the object with the same name cannot be overwritten. 
        "x-oss-forbid-overwrite": "true",
      };

      // Specify the name of the object that is uploaded to the examplebucket bucket. Example: exampleobject.txt. 
      const name = "exampleobject.txt";
      // Query DOM. 
      const submit = document.getElementById("submit");
      const data = document.getElementById("file").files[0];
      const options = {
        // Query the progress, the checkpoint, and the return value of the multipart upload task. 
        progress: (p, cpt, res) => {
          console.log(p);
        },
        // Specify the number of parts that can be uploaded in parallel. 
        parallel: 4,
        // Set the size available for each part. Default value: 1 MB. Minimum value: 100 KB. 
        partSize: 1024 * 1024,
        // headers,
        // Specify the user metadata of the object. You can call the HeadObject operation to query the object metadata. 
        meta: { year: 2020, people: "test" },
        mime: "text/plain",
      };

      // Create a button that is used to start the multipart upload task. 
      submit.addEventListener("click", async () => {
        try {
          // Start the multipart upload task. 
          const res = await client.multipartUpload(name, data, {
            // Configure upload callback. 
            callback: {
              // Specify the address of the server that receives the callback request. 
              url: "http://examplebucket.aliyuncs.com:23450",
              // Specify the Host header in the callback request. 
              host: "yourHost",
              /* eslint no-template-curly-in-string: [0] */
              // Specify the value of the body field included in the callback request. 
              body: "bucket=${bucket}&object=${object}&var1=${x:var1}",
              // Specify Content-Type in the callback request. 
              contentType: "application/x-www-form-urlencoded",
              customValue: {
                // Configure the custom parameters for the callback request. 
                var1: "value1",
                var2: "value2",
              },
            },
          });
        } catch (err) {
          console.log(err);
        }
      });
    </script>
  </body>
</html>
using Aliyun.OSS;

// Set yourEndpoint to the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set yourEndpoint to https://oss-cn-hangzhou.aliyuncs.com. 
var endpoint = "yourEndpoint";
// Security risks may arise if you use the AccessKey pair of an Alibaba Cloud account to access Object Storage Service (OSS) because the account has permissions on all API operations. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
var accessKeyId = "yourAccessKeyId";
var accessKeySecret = "yourAccessKeySecret";
// Specify the name of the bucket. 
var bucketName = "examplebucket";
// Specify the full path of the object. The full path cannot contain the name of the bucket. 
var objectName = "exampleobject.txt";
// Specify the full path of the local file that you want to upload. By default, if you do not specify the full path of the local file, the local file is uploaded from the path of the project to which the sample program belongs. 
var localFilename = "D:\\localpath\\examplefile.txt";
// Create an OSSClient instance. 
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);

// Initiate the multipart upload task and obtain the upload ID in the response. 
var uploadId = "";
try
{
    // Specify the name of the uploaded object and the bucket for the object. You can configure object metadata in InitiateMultipartUploadRequest. However, you do not need to specify ContentLength. 
    var request = new InitiateMultipartUploadRequest(bucketName, objectName);
    var result = client.InitiateMultipartUpload(request);
    uploadId = result.UploadId;
    // Display the upload ID. 
    Console.WriteLine("Init multi part upload succeeded");
    Console.WriteLine("Upload Id:{0}", result.UploadId);
}
catch (Exception ex)
{
    Console.WriteLine("Init multi part upload failed, {0}", ex.Message);
}
// Calculate the total number of parts. 
var partSize = 100 * 1024;
var fi = new FileInfo(localFilename);
var fileSize = fi.Length;
var partCount = fileSize / partSize;
if (fileSize % partSize != 0)
{
    partCount++;
}
// Start the multipart upload task. partETags is a list of PartETags. OSS verifies the validity of each part after it receives the list of parts. After all parts are verified, OSS combines these parts into a complete object. 
var partETags = new List<PartETag>();
try
{
    using (var fs = File.Open(localFilename, FileMode.Open))
    {
        for (var i = 0; i < partCount; i++)
        {
            var skipBytes = (long)partSize * i;
            // Find the start position of the current multipart upload task. 
            fs.Seek(skipBytes, 0);
            // Calculate the part size in this upload. The size of the last part is the size of the remainder after the object is split by the calculated part size. 
            var size = (partSize < fileSize - skipBytes) ? partSize : (fileSize - skipBytes);
            var request = new UploadPartRequest(bucketName, objectName, uploadId)
            {
                InputStream = fs,
                PartSize = size,
                PartNumber = i + 1
            };
            // Call UploadPart to upload parts. The returned results contain the ETag values of parts. 
            var result = client.UploadPart(request);
            partETags.Add(result.PartETag);
            Console.WriteLine("finish {0}/{1}", partETags.Count, partCount);
        }
        Console.WriteLine("Put multi part upload succeeded");
    }
}
catch (Exception ex)
{
    Console.WriteLine("Put multi part upload failed, {0}", ex.Message);
}
// Complete the multipart upload task. 
try
{
    var completeMultipartUploadRequest = new CompleteMultipartUploadRequest(bucketName, objectName, uploadId);
    foreach (var partETag in partETags)
    {
        completeMultipartUploadRequest.PartETags.Add(partETag);
    }
    var result = client.CompleteMultipartUpload(completeMultipartUploadRequest);
    Console.WriteLine("complete multi part succeeded");
}
catch (Exception ex)
{
    Console.WriteLine("complete multi part failed, {0}", ex.Message);
}
// Specify the name of the bucket to which you want to upload the object. Example: examplebucket. 
String bucketName = "examplebucket";
// Specify the full path of the object. Example: exampledir/exampleobject.txt. The full path of the object cannot contain the bucket name. 
String objectName = "exampledir/exampleobject.txt";
// Specify the full path of the local file that you want to upload to OSS by using multipart upload. Example: /storage/emulated/0/oss/examplefile.txt. 
String localFilepath = "/storage/emulated/0/oss/examplefile.txt";

// Initiate a multipart upload task. 
InitiateMultipartUploadRequest init = new InitiateMultipartUploadRequest(bucketName, objectName);
InitiateMultipartUploadResult initResult = oss.initMultipartUpload(init);
// Obtain the upload ID, which uniquely identifies the multipart upload task. You can use the upload ID to cancel or query the multipart upload task. 
String uploadId = initResult.getUploadId();

// Set the size of a single part. Unit: bytes. Valid values: 100 KB to 5 GB. 
int partCount = 100 * 1024;
// Implement the multipart upload task. 
List<PartETag> partETags = new ArrayList<>();
for (int i = 1; i < 5; i++) {
    byte[] data = new byte[partCount];

    RandomAccessFile raf = new RandomAccessFile(localFilepath, "r");
    long skip = (i-1) * partCount;
    raf.seek(skip);
    raf.readFully(data, 0, partCount);

    UploadPartRequest uploadPart = new UploadPartRequest();
    uploadPart.setBucketName(bucketName);
    uploadPart.setObjectKey(objectName);
    uploadPart.setUploadId(uploadId);
    // Set the part number for each part. The number starts from 1. Each part to upload has a part number. Valid values: 1 to 10000. 
    uploadPart.setPartNumber(i); 
    uploadPart.setPartContent(data);
    try {
        UploadPartResult result = oss.uploadPart(uploadPart);
        PartETag partETag = new PartETag(uploadPart.getPartNumber(), result.getETag());
        partETags.add(partETag);
    } catch (ServiceException serviceException) {
        OSSLog.logError(serviceException.getErrorCode());
    }
}
Collections.sort(partETags, new Comparator<PartETag>() {
    @Override
    public int compare(PartETag lhs, PartETag rhs) {
        if (lhs.getPartNumber() < rhs.getPartNumber()) {
            return -1;
        } else if (lhs.getPartNumber() > rhs.getPartNumber()) {
            return 1;
        } else {
            return 0;
        }
    }
});

// Complete the multipart upload task. 
CompleteMultipartUploadRequest complete = new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags);

// Configure upload callback. You can set the CALLBACK_SERVER parameter when you complete the multipart upload request. A callback request is sent to the specified server address after the multipart upload task is completed. You can view the servercallback result in completeResult.getServerCallbackReturnBody() of the response. 
complete.setCallbackParam(new HashMap<String, String>() {
    {
        put("callbackUrl", CALLBACK_SERVER); // Set the CALLBACK_SERVER parameter to your server address. 
        put("callbackBody", "test");
    }
});
CompleteMultipartUploadResult completeResult = oss.completeMultipartUpload(complete);
OSSLog.logError("-------------- serverCallback: " + completeResult.getServerCallbackReturnBody());
package main

import (
    "fmt"
    "os"

    "github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
    // Create an OSSClient instance. 
    // Set yourEndpoint to the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set yourEndpoint to https://oss-cn-hangzhou.aliyuncs.com. 
    // Security risks may arise if you use the AccessKey pair of an Alibaba Cloud account to access OSS because the account has permissions on all API operations. We recommend that you use a RAM user to call API operations or perform routine operations and maintenance. To create a RAM user, log on to the RAM console. 
    client, err := oss.New("yourEndpoint", "yourAccessKeyId", "yourAccessKeySecret")
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    // Specify the name of the bucket. 
    bucketName := "examplebucket"
    // Specify the full path of the object. The full path of the object cannot contain the bucket name. 
    objectName := "exampleobject.txt"
    // Specify the full path of the local file that you want to upload. By default, if you do not specify the full path of the local file, the local file is uploaded from the path of the project to which the sample program belongs. 
    locaFilename := "D:\\localpath\\examplefile.txt"

    bucket, err := client.Bucket(bucketName)
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    // Split the local file into three parts. 
    chunks, err := oss.SplitFileByPartNum(locaFilename, 3)
    fd, err := os.Open(locaFilename)
    defer fd.Close()
    
    // Specify the expiration time. 
    expires := time.Date(2049, time.January, 10, 23, 0, 0, 0, time.UTC)
    // The following code provides an example on how to specify the request headers when you initiate a multipart upload task. 
    options := []oss.Option{
        oss.MetadataDirective(oss.MetaReplace),
        oss.Expires(expires),
        // Specify the caching behavior of the web page when the object is downloaded. 
        // oss.CacheControl("no-cache"),
        // Specify the name of the object when the object is downloaded. 
        // oss.ContentDisposition("attachment;filename=FileName.txt"),
        // Specify the encoding format for the content of the object. 
        // oss.ContentEncoding("gzip"),
        // Specify the method that is used to encode the object name in the response. Only URL encoding is supported. 
        // oss.EncodingType("url"),
        // Specify the storage class of the object. 
        // oss.ObjectStorageClass(oss.StorageStandard),
    }

    // Step 1: Initiate a multipart upload task and set the storage class to Standard. 
    imur, err := bucket.InitiateMultipartUpload(objectName, options...)
    // Step 2: Upload parts. 
    var parts []oss.UploadPart
    for _, chunk := range chunks {
        fd.Seek(chunk.Offset, os.SEEK_SET)
        // Call the UploadPart method to upload each part. 
        part, err := bucket.UploadPart(imur, fd, chunk.Size, chunk.Number)
        if err != nil {
            fmt.Println("Error:", err)
            os.Exit(-1)
        }
        parts = append(parts, part)
    }

    // Set the access control list (ACL) of the object to public-read. By default, the object inherits the ACL of the bucket. 
    objectAcl := oss.ObjectACL(oss.ACLPublicRead)

    // Step 3: Complete the multipart upload task and set the ACL of the object to public-read. 
    cmur, err := bucket.CompleteMultipartUpload(imur, parts, objectAcl)
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    fmt.Println("cmur:", cmur)
}
__block NSString * uploadId = nil;
__block NSMutableArray * partInfos = [NSMutableArray new];
NSString * uploadToBucket = @"<bucketName>";
// objectKey is equivalent to objectName and specifies the full path of the object that you want to upload to OSS. The path must include the file extension of the object. For example, you can set objectKey to abc/efg/123.jpg.
NSString * uploadObjectkey = @"<objectKey>";
// You can use OSSInitMultipartUploadRequest to specify the name of the object you want to upload and specify the name of the bucket to which the object belongs. 
OSSInitMultipartUploadRequest * init = [OSSInitMultipartUploadRequest new];
init.bucketName = uploadToBucket;
init.objectKey = uploadObjectkey;
// init.contentType = @"application/octet-stream";
// The response to multipartUploadInit contains the upload ID. The upload ID is the unique ID of the multipart upload task. 
OSSTask * initTask = [client multipartUploadInit:init];
[initTask waitUntilFinished];
if (!initTask.error) {
    OSSInitMultipartUploadResult * result = initTask.result;
    uploadId = result.uploadId;
} else {
    NSLog(@"multipart upload failed, error: %@", initTask.error);
    return;
}
#include <alibabacloud/oss/OssClient.h>

int64_t getFileSize(const std::string& file)
{
    std::fstream f(file, std::ios::in | std::ios::binary);
    f.seekg(0, f.end);
    int64_t size = f.tellg();
    f.close();
    return size;
}

using namespace AlibabaCloud::OSS;

int main(void)
{
    /* Initialize the information about the account used to access OSS. */
    std::string AccessKeyId = "yourAccessKeyId";
    std::string AccessKeySecret = "yourAccessKeySecret";
    std::string Endpoint = "yourEndpoint";
    /* Specify the name of the bucket. Example: examplebucket. */
    std::string BucketName = "examplebucket";
    /* Specify the full path of the object. The full path cannot contain the name of the bucket. Example: exampledir/exampleobject.txt.  */
    std::string ObjectName = "exampledir/exampleobject.txt";

    /* Initialize resources such as networks. */
    InitializeSdk();

    ClientConfiguration conf;
    OssClient client(Endpoint, AccessKeyId, AccessKeySecret, conf);
    InitiateMultipartUploadRequest initUploadRequest(BucketName, ObjectName);
    /* Optional. Specify the storage class. */
    //initUploadRequest.MetaData().addHeader("x-oss-storage-class", "Standard");

    /* Initiate the multipart upload task. */
    auto uploadIdResult = client.InitiateMultipartUpload(initUploadRequest);
    auto uploadId = uploadIdResult.result().UploadId();
    std::string fileToUpload = "yourLocalFilename";
    int64_t partSize = 100 * 1024;
    PartList partETagList;
    auto fileSize = getFileSize(fileToUpload);
    int partCount = static_cast<int>(fileSize / partSize);
    /* Calculate the number of parts. */
    if (fileSize % partSize != 0) {
        partCount++;
    }

    /* Upload each part. */
    for (int i = 1; i <= partCount; i++) {
        auto skipBytes = partSize * (i - 1);
        auto size = (partSize < fileSize - skipBytes) ? partSize : (fileSize - skipBytes);
        std::shared_ptr<std::iostream> content = std::make_shared<std::fstream>(fileToUpload, std::ios::in|std::ios::binary);
        content->seekg(skipBytes, std::ios::beg);

        UploadPartRequest uploadPartRequest(BucketName, ObjectName, content);
        uploadPartRequest.setContentLength(size);
        uploadPartRequest.setUploadId(uploadId);
        uploadPartRequest.setPartNumber(i);
        auto uploadPartOutcome = client.UploadPart(uploadPartRequest);
        if (uploadPartOutcome.isSuccess()) {
            Part part(i, uploadPartOutcome.result().ETag());
            partETagList.push_back(part);
        }
        else {
            std::cout << "uploadPart fail" <<
            ",code:" << uploadPartOutcome.error().Code() <<
            ",message:" << uploadPartOutcome.error().Message() <<
            ",requestId:" << uploadPartOutcome.error().RequestId() << std::endl;
        }

    }

    /* Complete the multipart upload task. */
    CompleteMultipartUploadRequest request(BucketName, ObjectName);
    request.setUploadId(uploadId);
    request.setPartList(partETagList);
    /* Optional. Specify the ACL of the object. */
    //request.setAcl(CannedAccessControlList::Private);

    auto outcome = client.CompleteMultipartUpload(request);

    if (!outcome.isSuccess()) {
        /* Handle exceptions. */
        std::cout << "CompleteMultipartUpload fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        ShutdownSdk();
        return -1;
    }

    /* Release resources such as networks. */
    ShutdownSdk();
    return 0;
}
#include "oss_api.h"
#include "aos_http_io.h"
#include <sys/stat.h>
const char *endpoint = "<yourEndpoint>";
const char *access_key_id = "<yourAccessKeyId>";
const char *access_key_secret = "<yourAccessKeySecret>";
const char *bucket_name = "<yourBucketName>";
const char *object_name = "<yourObjectName>";
const char *local_filename = "<yourLocalFilename>";
void init_options(oss_request_options_t *options)
{
    options->config = oss_config_create(options->pool);
    /* Use a char* string to initialize the aos_string_t data type. */
    aos_str_set(&options->config->endpoint, endpoint);
    aos_str_set(&options->config->access_key_id, access_key_id);
    aos_str_set(&options->config->access_key_secret, access_key_secret);
    /* Determine whether CNAME is used. A value of 0 indicates that CNAME is not used. */
    options->config->is_cname = 0;
    /* Configure network parameters such as timeout. */
    options->ctl = aos_http_controller_create(options->pool, 0);
}
int64_t get_file_size(const char *file_path)
{
    int64_t filesize = -1;
    struct stat statbuff;
    if(stat(file_path, &statbuff) < 0){
        return filesize;
    } else {
        filesize = statbuff.st_size;
    }
    return filesize;
}
int main(int argc, char *argv[])
{
    /* Call aos_http_io_initialize in main() to initialize global resources such as the network and memory. */
    if (aos_http_io_initialize(NULL, 0) != AOSE_OK) {
        exit(1);
    }
    /* Create a memory pool to manage memory resources. The implementation code is included in the APR library. aos_pool_t is equivalent to apr_pool_t. */
    aos_pool_t *pool;
    /* Create a new memory pool. The second parameter value is NULL. This value indicates that the pool does not inherit any other memory pool. */
    aos_pool_create(&pool, NULL);
    /* Create and initialize options. This parameter includes global configuration information such as endpoint, access_key_id, access_key_secret, is_cname, and curl. */
    oss_request_options_t *oss_client_options;
    /* Allocate memory resources in the memory pool to options. */
    oss_client_options = oss_request_options_create(pool);
    /* Call oss_client_options to initialize the client options. */
    init_options(oss_client_options);
    /* Initialize parameters. */
    aos_string_t bucket;
    aos_string_t object;
    oss_upload_file_t *upload_file = NULL;
    aos_string_t upload_id;   
    aos_table_t *headers = NULL;
    aos_table_t *complete_headers = NULL;
    aos_table_t *resp_headers = NULL;
    aos_status_t *resp_status = NULL; 
    aos_str_set(&bucket, bucket_name);
    aos_str_set(&object, object_name);
    aos_str_null(&upload_id);
    headers = aos_table_make(pool, 1);
    complete_headers = aos_table_make(pool, 1);
    int part_num = 1;
    /* Initialize a multipart upload task and obtain an upload ID. */
    resp_status = oss_init_multipart_upload(oss_client_options, &bucket, &object, &upload_id, headers, &resp_headers);
    /* Determine whether the multipart upload task is initialized. */
    if (aos_status_is_ok(resp_status)) {
        printf("Init multipart upload succeeded, upload_id:%.*s\n", 
               upload_id.len, upload_id.data);
    } else {
        printf("Init multipart upload failed, upload_id:%.*s\n", 
               upload_id.len, upload_id.data);
    }
    /* Upload the parts. */
    int64_t file_length = 0;
    int64_t pos = 0;
    aos_list_t complete_part_list;
       oss_complete_part_content_t* complete_content = NULL;
    char* part_num_str = NULL;
    char* etag = NULL;
    aos_list_init(&complete_part_list);
    file_length = get_file_size(local_filename);
    while(pos < file_length) {
        upload_file = oss_create_upload_file(pool);
        aos_str_set(&upload_file->filename, local_filename);
        upload_file->file_pos = pos;
        pos += 100 * 1024;
        upload_file->file_last = pos < file_length ? pos : file_length;
        resp_status = oss_upload_part_from_file(oss_client_options, &bucket, &object, &upload_id, part_num++, upload_file, &resp_headers);

        /* Save the part numbers and ETags. */
        complete_content = oss_create_complete_part_content(pool);
        part_num_str = apr_psprintf(pool, "%d", part_num-1);
        aos_str_set(&complete_content->part_number, part_num_str);
        etag = apr_pstrdup(pool,
        (char*)apr_table_get(resp_headers, "ETag"));
        aos_str_set(&complete_content->etag, etag);
        aos_list_add_tail(&complete_content->node, &complete_part_list);

        if (aos_status_is_ok(resp_status)) {
            printf("Multipart upload part from file succeeded\n");
        } else {
            printf("Multipart upload part from file failed\n");
        }
    }

    /* Complete the multipart upload task. */
    resp_status = oss_complete_multipart_upload(oss_client_options, &bucket, &object, &upload_id,
            &complete_part_list, complete_headers, &resp_headers);
    /* Determine whether the multipart upload is complete. */
    if (aos_status_is_ok(resp_status)) {
        printf("Complete multipart upload from file succeeded, upload_id:%.*s\n", 
               upload_id.len, upload_id.data);
    } else {
        printf("Complete multipart upload from file failed\n");
    }
    /* Release the memory pool. The memory allocated to various resources used for the request is released. */
    aos_pool_destroy(pool);
    /* Release the allocated global resources. */
    aos_http_io_deinitialize();
    return 0;
}

Use ossutil

For more information about how to perform multipart upload by using ossutil, see Upload objects.

Use the RESTful API

If your business requires a high level of customization, you can directly call RESTful APIs. To directly call an API, you must include the signature calculation in your code. For more information, see InitiateMultipartUpload.