By using the multipart upload feature provided by OSS, you can split a large object into multiple parts and upload them separately. After all parts are uploaded, call the CompleteMultipartUpload operation to combine these parts into a single object to implement resumable upload.

Multipart upload process

To implement multipart upload, perform the following operations:

  1. Initiate a multipart upload task.

    Call the ossClient.initiateMultipartUpload method to obtain an upload ID that is unique in OSS.

  2. Upload parts.

    Call the ossClient.uploadPart method to upload the parts.

    Note
    • Part numbers identify the relative positions of parts in an object that share the same upload ID. If you upload a part that has the same part number as an existing part, the existing part is overwritten by the uploaded part.
    • OSS includes the MD5 hash of part data in the ETag header and returns the MD5 hash to the user.
    • OSS calculates the MD5 hash of uploaded data and compares the MD5 hash with the MD5 hash calculated by the SDK. If the two hashes are different, the InvalidDigest error code is returned.
  3. Complete the multipart upload task.

    After all parts are uploaded, call the ossClient.completeMultipartUpload method to combine these parts into a complete object.

For more information about multipart upload and its applicable scenarios, see Multipart upload. For the complete code used to perform multipart upload, visit GitHub.

A complete example of multipart upload

The following code provides a complete example that describes the process of multipart upload:

// Set yourEndpoint to the endpoint of the region in which the bucket is located. For example, if your bucket is located in the China (Hangzhou) region, set yourEndpoint to https://oss-cn-hangzhou.aliyuncs.com. 
String 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. 
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 bucket names. 
String objectName = "exampledir/exampleobject.txt";

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

// Create an InitiateMultipartUploadRequest object. 
InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, objectName);

// Optional. Specify the storage class. 
// ObjectMetadata metadata = new ObjectMetadata();
// metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
// 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 a set of PartETags. A PartETag consists of an ETag and a part number. 
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 to upload. By default, if you do not specify 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);
    // Set 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 order. They can be uploaded from different OSS clients. OSS sorts the parts based on their part numbers and combines them to obtain a complete object. 
    UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
    // When a part is uploaded, OSS returns a result that contains a PartETag. The PartETag is 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 OSS receives the partETags, OSS verifies the validity of all parts one by one. If part verification is successful, OSS combines these parts into a complete object. 
CompleteMultipartUploadRequest completeMultipartUploadRequest =
        new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags);

// Optional. Set the access control list (ACL). 
// completeMultipartUploadRequest.setObjectACL(CannedAccessControlList.PublicRead);

// Complete the multipart upload task. 
CompleteMultipartUploadResult completeMultipartUploadResult = ossClient.completeMultipartUpload(completeMultipartUploadRequest);
System.out.println(completeMultipartUploadResult.getETag());
// Shut down the OSSClient instance. 
ossClient.shutdown();

Cancel a multipart upload task

You can call the ossClient.abortMultipartUpload method to cancel a multipart upload task. If you cancel a multipart upload task, you cannot use the upload ID to upload parts. The uploaded parts are deleted.

The following code provides an example on how to cancel a multipart upload task:

// Set yourEndpoint to the endpoint of the region in which the bucket is located. For example, if your bucket is located in the China (Hangzhou) region, set yourEndpoint to https://oss-cn-hangzhou.aliyuncs.com. 
String 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 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 bucket names. 
String objectName = "exampledir/exampleobject.txt";
// Specify the upload ID. Example: 0004B999EF518A1FE585B0C9360D****. The upload ID is obtained from the response of InitiateMultipartUpload. 
String uploadId = "0004B999EF518A1FE585B0C9360D****";

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

// Cancel the multipart upload task. 
AbortMultipartUploadRequest abortMultipartUploadRequest =
        new AbortMultipartUploadRequest(bucketName, objectName, uploadId);
ossClient.abortMultipartUpload(abortMultipartUploadRequest);

// Shut down the OSSClient instance. 
ossClient.shutdown();            

List uploaded parts

You can call the ossClient.listParts method to list all parts that are uploaded by using the specified upload ID.

  • Simple list

    The following code provides an example on how to list uploaded parts:

    // Set yourEndpoint to the endpoint of the region in which the bucket is located. For example, if your bucket is located in the China (Hangzhou) region, set yourEndpoint to https://oss-cn-hangzhou.aliyuncs.com. 
    String 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 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 bucket names. 
    String objectName = "exampledir/exampleobject.txt";
    // Specify the upload ID. Example: 0004B999EF518A1FE585B0C9360D****. The upload ID is obtained from the response of InitiateMultipartUpload. 
    String uploadId = "0004B999EF518A1FE585B0C9360D****";
    
    // Create an OSSClient instance. 
    OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    
    // List uploaded parts. 
    ListPartsRequest listPartsRequest = new ListPartsRequest(bucketName, objectName, uploadId);
    // Set uploadId. 
    //listPartsRequest.setUploadId(uploadId);
    // Set the maximum number of parts that can be displayed on each page to 100. The default number is 1,000. 
    listPartsRequest.setMaxParts(100);
    // Specify the initial position in the list. Only the parts whose part numbers are greater than the value of this parameter are listed. 
    listPartsRequest.setPartNumberMarker(2);
    PartListing partListing = ossClient.listParts(listPartsRequest);
    
    for (PartSummary part : partListing.getParts()) {
        // Obtain part numbers. 
        part.getPartNumber();
        // Obtain the part size. 
        part.getSize();
        // Obtain the ETag. 
        part.getETag();
        // Obtain the last modified time. 
        part.getLastModified();
    }
    
    // Shut down the OSSClient instance. 
    ossClient.shutdown();                    
  • List all uploaded parts

    By default, listParts can list up to 1,000 parts at a time. To list more than 1,000 uploaded parts, use the following code:

    // Set yourEndpoint to the endpoint of the region in which the bucket is located. For example, if your bucket is located in the China (Hangzhou) region, set yourEndpoint to https://oss-cn-hangzhou.aliyuncs.com. 
    String 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 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 bucket names. 
    String objectName = "exampledir/exampleobject.txt";
    // Specify the upload ID. Example: 0004B999EF518A1FE585B0C9360D****. The upload ID is obtained from the response of InitiateMultipartUpload. 
    String uploadId = "0004B999EF518A1FE585B0C9360D****";
    
    // Create an OSSClient instance. 
    OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    
    // List all uploaded parts. 
    PartListing partListing;
    ListPartsRequest listPartsRequest = new ListPartsRequest(bucketName, objectName, uploadId);
    
    do {
        partListing = ossClient.listParts(listPartsRequest);
    
        for (PartSummary part : partListing.getParts()) {
            // Obtain part numbers. 
            part.getPartNumber();
            // Obtain the part size. 
            part.getSize();
            // Obtain the ETag. 
            part.getETag();
            // Obtain the last modified time. 
            part.getLastModified();
        }
    // Specify the start point of the list. Only the parts whose part numbers are greater than the value of this parameter are listed. 
    listPartsRequest.setPartNumberMarker(partListing.getNextPartNumberMarker());
    } while (partListing.isTruncated());
    
    // Shut down the OSSClient instance. 
    ossClient.shutdown();                   
  • List all uploaded parts by page

    The following code provides an example on how to specify the maximum number of parts to list per page and list all uploaded parts by page:

    // Set yourEndpoint to the endpoint of the region in which the bucket is located. For example, if your bucket is located in the China (Hangzhou) region, set yourEndpoint to https://oss-cn-hangzhou.aliyuncs.com. 
    String 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 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 bucket names. 
    String objectName = "exampledir/exampleobject.txt";
    // Specify the upload ID. Example: 0004B999EF518A1FE585B0C9360D****. The upload ID is obtained from the response of InitiateMultipartUpload. 
    String uploadId = "0004B999EF518A1FE585B0C9360D****";
    
    
    // Create an OSSClient instance. 
    OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    
    // List all uploaded parts on one or more pages. 
    PartListing partListing;
    ListPartsRequest listPartsRequest = new ListPartsRequest(bucketName, objectName, uploadId);
    // Set the maximum number of parts to list per page to 100. 
    listPartsRequest.setMaxParts(100);
    
    do {
        partListing = ossClient.listParts(listPartsRequest);
    
        for (PartSummary part : partListing.getParts()) {
            // Obtain part numbers. 
            part.getPartNumber();
            // Obtain the part size. 
            part.getSize();
            // Obtain the ETag. 
            part.getETag();
            // Obtain the last modified time. 
            part.getLastModified();
        }
    
        listPartsRequest.setPartNumberMarker(partListing.getNextPartNumberMarker());
    
    } while (partListing.isTruncated());
    
    // Shut down the OSSClient instance. 
    ossClient.shutdown();                    

List multipart upload tasks

You can call the ossClient.listMultipartUploads method to list all ongoing multipart upload tasks. Ongoing multipart upload tasks are tasks that are initiated but incomplete or tasks that are canceled. The following table describes the parameters that you can configure to list these tasks.

Parameter Purpose Method
prefix The prefix that the names of returned objects must contain. If you use a prefix for a query, the returned object names contain the prefix. ListMultipartUploadsRequest.setPrefix(String prefix)
delimiter The character used to group object names. The substring between the specified prefix and the occurrence of the first delimiter is commonPrefixes. A substring of object names starts with the prefix and ends with the next occurrence of the specified delimiter. ListMultipartUploadsRequest.setDelimiter(String delimiter)
maxUploads The maximum number of multipart upload tasks to list in this query. The default value is 1000. The maximum value is 1000. ListMultipartUploadsRequest.setMaxUploads(Integer maxUploads)
keyMarker Specifies the name of the object after which the listing of multipart upload tasks begins. All multipart upload tasks where objects whose names start with a letter that is alphabetically after the keyMarker parameter value are listed. You can use this parameter with the uploadIdMarker parameter to specify the start point to list the returned results. ListMultipartUploadsRequest.setKeyMarker(String keyMarker)
uploadIdMarker UploadIdMarker is used with the keyMarker parameter to specify the start point to list the returned results. If the keyMarker parameter is not configured, the uploadIdMarker parameter is invalid. If the keyMarker parameter is specified, the query result includes:
  • All objects whose names start with a letter that is alphabetically after the keyMarker parameter value in alphabetical order.
  • All objects whose names start with a letter that is the same as the keyMarker parameter value in alphabetical order and of which the uploadId parameter value is greater than the uploadIdMarker parameter value.
ListMultipartUploadsRequest.setUploadIdMarker(String uploadIdMarker)
  • Simple list

    The following code provides an example on how to list multipart upload tasks:

    // Set yourEndpoint to the endpoint of the region in which the bucket is located. For example, if your bucket is located in the China (Hangzhou) region, set yourEndpoint to https://oss-cn-hangzhou.aliyuncs.com. 
    String 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 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";
    
    // Create an OSSClient instance. 
    OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    
    // List multipart upload tasks. The default number is 1,000. 
    ListMultipartUploadsRequest listMultipartUploadsRequest = new ListMultipartUploadsRequest(bucketName);
    MultipartUploadListing multipartUploadListing = ossClient.listMultipartUploads(listMultipartUploadsRequest);
    
    for (MultipartUpload multipartUpload : multipartUploadListing.getMultipartUploads()) {
        // Obtain upload IDs. 
        multipartUpload.getUploadId();
        // Obtain object names. 
        multipartUpload.getKey();
        // Obtain the time the multipart upload tasks are initiated. 
        multipartUpload.getInitiated();
    }
    
    // Shut down the OSSClient instance. 
    ossClient.shutdown();                    

    If the value of the isTruncated field in the returned result is false, values of nextKeyMarker and nextUploadIdMarker are returned and used as the start point for the next reading. If the response does not contain all multipart upload tasks, list multipart upload tasks by page.

  • List all multipart upload tasks

    By default, listMultipartUploads can list up to 1,000 multipart upload tasks at a time. The following code provides an example on how to list more than 1,000 multipart upload tasks:

    // Set yourEndpoint to the endpoint of the region in which the bucket is located. For example, if your bucket is located in the China (Hangzhou) region, set yourEndpoint to https://oss-cn-hangzhou.aliyuncs.com. 
    String 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 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";
    
    // Create an OSSClient instance. 
    OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    
    // List multipart upload tasks. 
    MultipartUploadListing multipartUploadListing;
    ListMultipartUploadsRequest listMultipartUploadsRequest = new ListMultipartUploadsRequest(bucketName);
    
    do {
        multipartUploadListing = ossClient.listMultipartUploads(listMultipartUploadsRequest);
    
        for (MultipartUpload multipartUpload : multipartUploadListing.getMultipartUploads()) {
            // Obtain upload IDs. 
            multipartUpload.getUploadId();
            // Obtain object names. 
            multipartUpload.getKey();
            // Obtain the time the multipart upload tasks are initiated. 
            multipartUpload.getInitiated();
        }
    
        listMultipartUploadsRequest.setKeyMarker(multipartUploadListing.getNextKeyMarker());
    
        listMultipartUploadsRequest.setUploadIdMarker(multipartUploadListing.getNextUploadIdMarker());
    } while (multipartUploadListing.isTruncated());
    
    // Shut down the OSSClient instance. 
    ossClient.shutdown();                    
  • List multipart upload tasks on one or more pages

    The following code provides an example on how to list all multipart upload tasks by page:

    // Set yourEndpoint to the endpoint of the region in which the bucket is located. For example, if your bucket is located in the China (Hangzhou) region, set yourEndpoint to https://oss-cn-hangzhou.aliyuncs.com. 
    String 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 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";
    
    // Create an OSSClient instance. 
    OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    
    // List multipart upload tasks. 
    MultipartUploadListing multipartUploadListing;
    ListMultipartUploadsRequest listMultipartUploadsRequest = new ListMultipartUploadsRequest(bucketName);
    // Specify the number of multipart upload tasks to list on each page. 
    listMultipartUploadsRequest.setMaxUploads(50);
    
    do {
        multipartUploadListing = ossClient.listMultipartUploads(listMultipartUploadsRequest);
    
        for (MultipartUpload multipartUpload : multipartUploadListing.getMultipartUploads()) {
            // Obtain upload IDs. 
            multipartUpload.getUploadId();
            // Obtain object names. 
            multipartUpload.getKey();
            // Obtain the time the multipart upload tasks are initiated. 
            multipartUpload.getInitiated();
        }
    
        listMultipartUploadsRequest.setKeyMarker(multipartUploadListing.getNextKeyMarker());
        listMultipartUploadsRequest.setUploadIdMarker(multipartUploadListing.getNextUploadIdMarker());
    
    } while (multipartUploadListing.isTruncated());
    
    // Shut down the OSSClient instance. 
    ossClient.shutdown();