When you use the resumable upload feature to upload objects to Object Storage Service (OSS), you can specify a checkpoint file. The checkpoint file stores the information about the resumable upload task. If an object fails to be uploaded because of a network exception or program error, the upload task is resumed from the position recorded in the checkpoint file.

Prerequisites

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

Usage notes

You can perform resumable upload only by using OSS SDKs. Take note of the following precautions when you use resumable upload:

  • During resumable upload, the upload progress is recorded in a checkpoint file. If a part fails to be uploaded, the next upload starts from the position recorded in the checkpoint file. After the object is uploaded, the checkpoint file is deleted.
  • The upload progress is recorded in the checkpoint file. Make sure that you have write permissions on the checkpoint file.
  • The checkpoint file contains a checksum. This checksum cannot be edited. If the checkpoint file is damaged, you must upload all parts of the object again.
  • If the local file is modified during the upload, you must upload all parts of the object again.

Use OSS SDKs

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

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.*;

public class Demo {
    public static void main(String[] args) {
        // 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";

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

            ObjectMetadata meta = new ObjectMetadata();
            // Specify the type of content that you want to upload. 
            meta.setContentType("text/plain");

            // Specify the access control list (ACL) of the object to upload. 
            // meta.setObjectAcl(CannedAccessControlList.Private);

            // Configure parameters by using UploadFileRequest. 
            // Specify the bucket name and the full path of the object, and the full path cannot contain the bucket name. Examples: examplebucket for the bucket name and exampledir/exampleobject.txt for the path of the object. 
            UploadFileRequest uploadFileRequest = new UploadFileRequest("examplebucket","exampledir/exampleobject.txt");

            // Configure a single parameter by using UploadFileRequest.            
            // Specify the full path of the local file. Example: D:\\localpath\\examplefile.txt. 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. 
            uploadFileRequest.setUploadFile("D:\\localpath\\examplefile.txt");
            // Specify the number of threads that can be concurrently processed. Default value: 1. 
            uploadFileRequest.setTaskNum(5);
            // Specify the size of each part. Unit: bytes. Valid values: 100 KB to 5 GB. Default value: 100 KB. 
            uploadFileRequest.setPartSize(1 * 1024 * 1024);
            // Specify whether to enable resumable upload. By default, resumable upload is disabled. 
            uploadFileRequest.setEnableCheckpoint(true);
            // Specify the checkpoint file that records the upload result of each part. This file stores information about upload progress. If a part fails to upload, the task can be continued based on the progress recorded in the checkpoint file. After the object is uploaded, the checkpoint file is deleted. 
            // By default, if you do not specify this parameter, this checkpoint file shares the same directory as the object you want to upload. The directory is named ${uploadFile}.ucp. 
            uploadFileRequest.setCheckpointFile("yourCheckpointFile");
            // Configure object metadata. 
            uploadFileRequest.setObjectMetadata(meta);
            // Configure upload callback. The parameter type is Callback. 
            //uploadFileRequest.setCallback("yourCallbackEvent");

            // Start resumable upload. 
            ossClient.uploadFile(uploadFileRequest);

        } 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 (Throwable 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 {
                // Shut down the OSSClient instance. 
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}           
let OSS = require('ali-oss');

let client = new OSS({
  region: '<Your region>',
  accessKeyId: '<Your AccessKeyId>',
  accessKeySecret: '<Your AccessKeySecret>',
  bucket: '<Your bucket name>',
});

let checkpoint;
async function resumeUpload() {
  // retry 5 times
  for (let i = 0; i < 5; i++) {
    try {
      const result = await client.multipartUpload('object-name', filePath, {
        checkpoint,
        async progress(percentage, cpt) {
          checkpoint = cpt;
        },
      });
      console.log(result);
      break; // break if success
    } catch (e) {
      console.log(e);
    }
  }
}

resumeUpload();
        
# -*- coding: utf-8 -*-
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')
# Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. 
# Specify the bucket name. Example: examplebucket. 
bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'examplebucket')

# Set yourObjectName to the full path of the object. The full path cannot contain the bucket name. Example: exampledir/exampleobject.txt. 
# Set yourLocalFile to the full path of the local file. Example: D:\\localpath\\examplefile.txt. 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. 
oss2.resumable_upload(bucket, 'exampledir/exampleobject.txt', 'D:\\localpath\\examplefile.txt')
# If you do not specify a directory by using the store parameter, the py-oss-upload directory is created in the HOME directory to store the checkpoint information. 

# OSS SDK for Python V2.1.0 and later support the configuration of optional parameters in resumable upload. The following code provides an example on how to configure optional parameters in resumable upload: 
# import sys
# # If the size of the data to upload cannot be determined, the total_bytes parameter is set to None. 
# def percentage(consumed_bytes, total_bytes):
#     if total_bytes:
#         rate = int(100 * (float(consumed_bytes) / float(total_bytes)))
#         print('\r{0}% '.format(rate), end='')
#         sys.stdout.flush()
# If you use the store parameter to specify a directory, the checkpoint information is stored in the specified directory. If you use the num_threads parameter to specify the number of concurrent upload threads, make sure that the oss2.defaults.connection_pool_size value is greater than or equal to the number of concurrent upload threads. The default number of concurrent upload threads is 1. 
# oss2.resumable_upload(bucket, '<yourObjectName>', '<yourLocalFile>',
#                       store=oss2.ResumableStore(root='/tmp'),
#                       # Specify that multipart upload is used when the object size is greater than or equal to the value of the multipart_threshold parameter. The default value of the parameter is 10 MB. 
#                       multipart_threshold=100*1024,
#                       # Specify the size of each part. Unit: bytes. Valid values: 100 KB to 5 GB. Default value: 100 KB. 
#                       part_size=100*1024,
#                       # Configure the function used to indicate the progress of the resumable upload task by implementing upload callback. 
#                       progress_callback=percentage,
#                       # If you use the num_threads parameter to specify the number of concurrent upload threads, make sure that the oss2.defaults.connection_pool_size value is greater than or equal to the number of concurrent upload threads. The default number of concurrent upload threads is 1. 
#                       num_threads=4)
using Aliyun.OSS;
using Aliyun.OSS.Common;

// 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 OSS because the account has permissions on all API operations. We recommend that you use a Resource Access Management (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 to which you want to upload the object. Example: examplebucket. 
var bucketName = "examplebucket";
// Specify the full path of the object. Example: exampledir/exampleobject.txt. The full path of the object cannot contain the bucket name. 
var objectName = "exampledir/exampleobject.txt";
// Specify the full path of the local file to upload. Example: D:\\localpath\\examplefile.txt. 
// By default, if you specify only the name of the local file such as examplefile.txt without specifying the local path, the local file is uploaded from the path of the project to which the sample program belongs. 
var localFilename = "D:\\localpath\\examplefile.txt";
// Specify the checkpoint file that records the upload result of each part. The file stores the progress information generated in the upload process. 
string checkpointDir = "yourCheckpointDir";
// Create an OSSClient instance. 
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
try
{
    // Configure parameters by using UploadFileRequest. 
    UploadObjectRequest request = new UploadObjectRequest(bucketName, objectName, localFilename)
    {
        // Specify the size of each part to upload. 
        PartSize = 8 * 1024 * 1024,
        // Specify the number of concurrent threads. 
        ParallelThreadCount = 3,
        // Set the checkpointDir parameter to store the state of the resumable upload, which is used to resume the upload when the upload fails. 
        // If you set checkpointDir to null, resumable upload does not take effect and the object is uploaded again when it fails to be uploaded. 
        CheckpointDir = checkpointDir,
    };
    // Start resumable upload. 
    client.ResumableUploadObject(request);
    Console.WriteLine("Resumable upload object:{0} succeeded", objectName);
}
catch (OssException ex)
{
    Console.WriteLine("Failed with error code: {0}; Error info: {1}. \nRequestID:{2}\tHostID:{3}",
        ex.ErrorCode, ex.Message, ex.RequestId, ex.HostId);
}
catch (Exception ex)
{
    Console.WriteLine("Failed with error info: {0}", ex.Message);
}
// 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 bucket names. 
String objectName = "exampledir/exampleobject.txt";
// Specify the full path of the local file. Example: /storage/emulated/0/oss/examplefile.txt. 
String localFilepath = "/storage/emulated/0/oss/examplefile.txt";

String recordDirectory = Environment.getExternalStorageDirectory().getAbsolutePath() + "/oss_record/";

File recordDir = new File(recordDirectory);

// Make sure that the folder for the checkpoint file exists. If the folder does not exist, create a folder. 
if (!recordDir.exists()) {
    recordDir.mkdirs();
}

// Create a resumable upload request and specify the absolute path of the checkpoint file. 
ResumableUploadRequest request = new ResumableUploadRequest(bucketName, objectName, localFilepath, recordDirectory);
// Set the DeleteUploadOnCancelling parameter when the OSSAsyncTask cancel() method is called. When this parameter is set to false, the checkpoint file is retained. If you do not specify this parameter, default value true is used, which indicates that the checkpoint file is deleted. The entire object is uploaded again during the next upload. 
request.setDeleteUploadOnCancelling(false);
// Configure upload callback. 
request.setProgressCallback(new OSSProgressCallback<ResumableUploadRequest>() {
    @Override
    public void onProgress(ResumableUploadRequest request, long currentSize, long totalSize) {
        Log.d("resumableUpload", "currentSize: " + currentSize + " totalSize: " + totalSize);
    }
});


ResumableUploadResult uploadResult = oss.resumableUpload(request);
package main

import (
    "fmt"
    "os"
    "github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
    // Create an OSSClient instance. 
    // Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. Specify your actual endpoint. 
    // 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. 
    client, err := oss.New("yourEndpoint", "yourAccessKeyId", "yourAccessKeySecret")
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // Specify the bucket name. Example: examplebucket. 
    bucket, err := client.Bucket("examplebucket")
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // Set the part size to 100 KB (100 × 1024), set the number of concurrent upload threads to 3, and enable resumable upload. 
    // Set yourObjectName to the full path of the object. The full path cannot contain the bucket name. Example: exampledir/exampleobject.txt. 
    // Set yourLocalFile to the full path of the local file. Example: D:\\localpath\\examplefile.txt. 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. 
    err = bucket.UploadFile("exampledir/exampleobject.txt", "D:\\localpath\\examplefile.txt", 100*1024, oss.Routines(3), oss.Checkpoint(true, ""))
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
}            
// Obtain an upload ID to upload an object.
OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];
resumableUpload.bucketName = <bucketName>;
// objectKey is equivalent to objectName that indicates the complete path of the object you want to upload to OSS by using resumable upload. The path must include the extension of the object. For example, you can set objectKey to abc/efg/123.jpg.
resumableUpload.objectKey = <objectKey>;
resumableUpload.partSize = 1024 * 1024;
resumableUpload.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {
    NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);
};
NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
// Specify the path to store the checkpoint file.
resumableUpload.recordDirectoryPath = cachesDir;
// Set the deleteUploadOnCancelling parameter to NO. NO indicates that the checkpoint file is not deleted when the upload task fails. The next upload starts from the position recorded in the checkpoint file to upload the entire object. If you do not specify this parameter, default value YES is used. YES indicates that the checkpoint file is deleted when the upload task fails. The entire object is uploaded again during the next upload.
resumableUpload.deleteUploadIdOnCancelling = NO;

resumableUpload.uploadingFileURL = [NSURL fileURLWithPath:<your file path>];
OSSTask * resumeTask = [client resumableUpload:resumableUpload];
[resumeTask continueWithBlock:^id(OSSTask *task) {
    if (task.error) {
        NSLog(@"error: %@", task.error);
        if ([task.error.domain isEqualToString:OSSClientErrorDomain] && task.error.code == OSSClientErrorCodeCannotResumeUpload) {
            // The task cannot be resumed. You must obtain a new upload ID to upload the object.
        }
    } else {
        NSLog(@"Upload file success");
    }
    return nil;
}];

// [resumeTask waitUntilFinished];

// [resumableUpload cancel];
                    
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* Initialize the information about the account used to access OSS. */
    /* 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. */
    std::string AccessKeyId = "yourAccessKeyId";
    std::string AccessKeySecret = "yourAccessKeySecret";
    /* 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 the endpoint to https://oss-cn-hangzhou.aliyuncs.com. */
    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 bucket name. Example: exampledir/exampleobject.txt. */
    std::string ObjectName = "exampledir/exampleobject.txt";
    /* Specify the full path of the local file. Example: D:\\localpath\\examplefile.txt. 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. */
    std::string UploadFilePath = "D:\\localpath\\examplefile.txt";
    /* Specify the checkpoint file that records the results of the multipart upload task. This file stores information about upload progress. If a part cannot be uploaded, the task can be resumed based on the progress recorded in the checkpoint file. After the object is uploaded, the checkpoint file is deleted. */
    /* By default, if you do not specify the path of the checkpoint file, the checkpoint file and the local file to upload share the same path. */
    std::string CheckpointFilePath = "yourCheckpointFilepath"

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

    ClientConfiguration conf;
    OssClient client(Endpoint, AccessKeyId, AccessKeySecret, conf);

    /* Start resumable upload. */
    UploadObjectRequest request(BucketName, ObjectName, UploadFilePath, CheckpointFilePath);
    auto outcome = client.ResumableUploadObject(request);

    if (!outcome.isSuccess()) {
        /* Handle exceptions. */
        std::cout << "ResumableUploadObject 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"
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 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);
    /* Deternube whether the CNAME is used. 0 indicates that it is not used. */
    options->config->is_cname = 0;
    /* Used to configure network parameters, such as timeout. */
    options->ctl = aos_http_controller_create(options->pool, 0);
}
int main(int argc, char *argv[])
{
    /* Call the aos_http_io_initialize method in main() to initialize global resources, such as networks and memories. */
    if (aos_http_io_initialize(NULL, 0) != AOSE_OK) {
        exit(1);
    }
    /* Memory pool used to manage memories, which is equivalent to apr_pool_t. The implementation code is included in the apr library. */
    aos_pool_t *pool;
    /* Re-create a new memory pool. The second parameter is NULL, indicating that it does not inherit from any other memory pools. */
    aos_pool_create(&pool, NULL);
    /* Create and initialize options. This parameter mainly includes global configuration information, such as endpoint, access_key_id, acces_key_secret, is_cname, and curl. */
    oss_request_options_t *oss_client_options;
    /* Allocate memories in the memory pool to options. */
    oss_client_options = oss_request_options_create(pool);
    /* Use oss_client_options to initialize client options */
    init_options(oss_client_options);
    /* Initialization parameters. */
    aos_string_t bucket;
    aos_string_t object;
    aos_string_t file;
    aos_list_t resp_body;
    aos_table_t *headers = NULL;
    aos_table_t *resp_headers = NULL; 
    aos_status_t *resp_status = NULL; 
    oss_resumable_clt_params_t *clt_params;
    aos_str_set(&bucket, bucket_name);
    aos_str_set(&object, object_name);
    aos_str_set(&file, local_filename);
    aos_list_init(&resp_body);
    /* Resumable upload. */
    clt_params = oss_create_resumable_clt_params_content(pool, 1024 * 100, 3, AOS_TRUE, NULL);
    resp_status = oss_resumable_upload_file(oss_client_options, &bucket, &object, &file, headers, NULL, clt_params, NULL, &resp_headers, &resp_body);
    if (aos_status_is_ok(resp_status)) {
        printf("resumable upload succeeded\n");
    } else {
        printf("resumable upload failed\n");
    }
    /* Release the memory pool, that is, memories allocated to resources during the request. */
    aos_pool_destroy(pool);
    /* Release allocated global resources. */
    aos_http_io_deinitialize();
    return 0;
}
require 'aliyun/oss'

client = Aliyun::OSS::Client.new(
  endpoint: 'endpoint',
  access_key_id: 'AccessKeyId', access_key_secret: 'AccessKeySecret')

bucket = client.get_bucket('my-bucket')

callback = Aliyun::OSS::Callback.new(
  url: 'http://10.101.168.94:1234/callback',
  query: {user: 'put_object'},
  body: 'bucket=${bucket}&object=${object}'
)

begin
  bucket.resumable_upload('files/hello', '/tmp/x', callback: callback)
rescue Aliyun::OSS::CallbackError => e
  puts "Callback failed: #{e.message}"
end