Alibaba Cloud Object Storage Service (OSS) provides multipart upload to allow you to split a large object into multiple parts and separately upload the parts. 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 an object that is larger than 5 GB in size, you can use multipart upload to split the object into multiple parts and concurrently upload the parts to accelerate the upload.
- Unstable network connections
We recommend that you use multipart upload when network connections are unstable. If specific parts fail to be uploaded, you need to upload only the failed parts.
- Unknown object size
If you do not know the sizes of the objects that you want to upload, you can use multipart upload. This case is common in industrial applications such as video surveillance.
Process

The preceding process consists of the following steps:
oss:PutObject
permission is required to complete a multipart upload task. A multipart upload task consists of three steps: multiplart upload initiation, part upload, and part combination. For more information, see Attach a custom policy to a RAM user. - Split the object that you want to upload into parts based on a specific size.
- Call the InitiateMultipartUpload operation to initiate a multipart upload task.
- Call the UploadPart operation to upload the parts. After the object is split into parts, specify a value for the
partNumber
parameter of each part to indicate the sequence of the parts. This facilitates the concurrent upload of the parts. More uploads in parallel do not necessarily result in a shorter upload process. We recommend that you specify the number of parallel uploads based on your network conditions and the workload of your devices.To cancel a multipart upload task, call the AbortMultipartUpload operation. After the multipart upload task is canceled, the parts that have been uploaded in the task are deleted.
- Call the CompleteMultipartUpload operation to combine the uploaded parts into an object.
Limits
Item | Description |
---|---|
Object size | Multipart upload supports objects of 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 10,000. |
Part size | A part, except for the last one, must be 100 KB to 5 GB in size. The last part can be smaller than 100 KB. |
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 tasks can be returned for a single ListMultipartUploads request. |
Usage notes
- Optimize object upload performance
If you upload a large number of objects whose names contain sequential prefixes, such as timestamps and letters, multiple 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 whose names contain sequential prefixes. 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 accidentally 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 the x-oss-forbid-overwrite header 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 that has the same name as an existing object, the upload fails and OSS returns theFileAlreadyExists
error. For more information, see InitiateMultipartUpload.
- Enable versioning
- Delete partsWhen a multipart upload task is interrupted, the parts that are uploaded by the task are stored in the specified bucket. To prevent additional storage fees, we recommend that you use one of the following methods to delete these parts if you no longer need these parts:
- Manually delete the parts. For more information, see Manage parts.
- Configure lifecycle rules to automatically delete the parts. For more information, see Configure lifecycle rules.
Use OSS SDKs
The following sample 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";
// 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.
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. Do not include the bucket name in the full path of the object.
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 it 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 that have the same names when the multipart upload task is initiated. In this example, this parameter is set to true, which indicates that existing objects cannot be overwritten by objects with the same names.
// metadata.setHeader("x-oss-forbid-overwrite", "true");
// Specify the server-side encryption method that you want to use to encrypt each part of the object.
// 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);
// Specify tags 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);
// Initialize the multipart upload 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. The PartETag of a part consists of the part number and ETag value of the 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.
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 parts that have been uploaded.
instream.skip(startPos);
UploadPartRequest uploadPartRequest = new UploadPartRequest();
uploadPartRequest.setBucketName(bucketName);
uploadPartRequest.setKey(objectName);
uploadPartRequest.setUploadId(uploadId);
uploadPartRequest.setInputStream(instream);
// Specify the size of each part. Each part except the last part must be equal to or greater than 100 KB in size.
uploadPartRequest.setPartSize(curPartSize);
// Specify 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 and can be uploaded from different OSS clients. OSS sorts the parts based on the part numbers and combines the parts 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 you call the CompleteMultipartUpload operation, you must provide all valid partETags. After OSS receives the partETags, OSS verifies all parts one by one. After part verification is successful, OSS combines these parts into a complete object.
CompleteMultipartUploadRequest completeMultipartUploadRequest =
new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags);
// The following code provides an example on how to configure the access control list (ACL) of the object when the multipart upload task is completed:
// completeMultipartUploadRequest.setObjectACL(CannedAccessControlList.Private);
// Specify 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 on the server side, you can leave partETags contained in CompleteMultipartUploadRequest empty.
// Map<String, String> headers = new HashMap<String, String>();
// 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. If you specify the request body, 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;
// 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';
// In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint.
$endpoint = 'https://oss-cn-hangzhou.aliyuncs.com';
// Specify the name of the bucket. Example: examplebucket.
$bucket= 'examplebucket';
// Specify the full path of the object. The full path of the object cannot contain the bucket name. Example: exampledir/exampleobject.txt.
$object = 'exampledir/exampleobject.txt';
// Specify the full path of the local file.
$uploadFile = 'D:\\localpath\\examplefile.txt';
$options = array(
'headers' => array(
// Specify the caching behavior of the web page when the object is downloaded.
// 'Cache-Control' => 'no-cache',
// Specify the name of the downloaded object.
// 'Content-Disposition' => 'attachment;filename=oss_download.jpg',
// 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' => 150,
// Specify whether the object that is uploaded by using multipart upload overwrites the existing object that has the same name when the multipart upload task is initiated. In this example, the x-oss-forbid-overwrite parameter is set to true, which specifies that existing objects cannot be overwritten by objects that have the same names.
// 'x-oss-forbid-overwrite' => 'true',
// Specify the server-side encryption method that you want to use to encrypt each part of the object.
// 'x-oss-server-side-encryption'=> 'KMS',
// Specify the algorithm that is used to encrypt the object.
// 'x-oss-server-side-data-encryption'=>'SM4',
// Specify the ID of the customer master key (CMK) that is managed by Key Management Service (KMS).
//'x-oss-server-side-encryption-key-id' => '9468da86-3509-4f8d-a61e-6eab1eac****',
// Specify the storage class of the object.
// 'x-oss-storage-class' => 'Standard',
// Specify tags for the object. You can specify multiple tags at a time.
// 'x-oss-tagging' => 'TagA=A&TagB=B',
),
);
/**
* Step 1: Initiate a multipart upload task and obtain the upload ID.
*/
try{
$ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, $options);
// Obtain the upload ID. The upload ID is the unique identifier for a multipart upload task. You can perform related operations such as canceling or querying the 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 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(
// Upload the local file.
$ossClient::OSS_FILE_UPLOAD => $uploadFile,
// Specify part numbers.
$ossClient::OSS_PART_NUM => ($i + 1),
// Specify the position from which the multipart upload task starts.
$ossClient::OSS_SEEK_TO => $fromPos,
// Specify the object length.
$ossClient::OSS_LENGTH => $toPos - $fromPos + 1,
// Specify whether to enable MD5 verification. A value of true indicates that 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");
}
// The $uploadParts parameter is an array that consists of the ETag and PartNumber parameters of each part.
$uploadParts = array();
foreach ($responseUploadPart as $i => $eTag) {
$uploadParts[] = array(
'PartNumber' => ($i + 1),
'ETag' => $eTag,
);
}
/**
* Step 3: Complete the multipart upload task.
*/
$options['headers'] = array(
// Specify whether the object that is uploaded by using multipart upload overwrites the existing object that has the same name when the multipart upload task is completed. In this example, the x-oss-forbid-overwrite parameter is set to true, which specifies that existing objects cannot be overwritten by objects that have the same names.
// 'x-oss-forbid-overwrite' => 'true',
// If you set the x-oss-complete-all parameter to yes, 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.
// 'x-oss-complete-all'=> 'yes'
);
try {
// All valid values of the $uploadParts parameter are required for the CompleteMultipartUpload operation. After OSS receives the values of the $uploadParts parameter, OSS verifies all parts one by one. After all parts are verified, 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 storage class of the object.
'x-oss-storage-class': 'Standard',
// Specify tags for the object. You can specify multiple tags for the object.
'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 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, and you do not specify 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 the metadata for the object. You can call the HeadObject operation to obtain 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
# 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.
auth = oss2.Auth('yourAccessKeyId', 'yourAccessKeySecret')
# In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint.
# 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. Do not include the bucket name in the full path. 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 operation.
# 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 the object that is uploaded by performing multipart upload overwrites the existing object that has the same name when the multipart upload task is initiated. 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 uploaded object.
# headers[OSS_SERVER_SIDE_ENCRYPTION] = SERVER_SIDE_ENCRYPTION_KMS
# Specify the algorithm that you want to use 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 destination object. You can specify multiple tags for the destination 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 position from which the append operation starts.
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 sample code provides an example on how to configure headers when you complete the multipart upload task:
headers = dict()
# Specify the ACL of the object. In this example, this parameter is set to OBJECT_ACL_PRIVATE, which specifies that the ACL of the object is private.
# headers["x-oss-object-acl"] = oss2.OBJECT_ACL_PRIVATE
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({
// 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",
// Specify the temporary AccessKey pair obtained from Security Token Service (STS). An AccessKey pair consists of an AccessKey ID and an AccessKey secret.
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 tags for the object. You can specify multiple tags at the same time.
"x-oss-tagging": "Tag1=1&Tag2=2",
// Specify whether the object that is uploaded by using multipart upload overwrites the existing object that has the same name when the multipart upload task is initiated. In this example, the x-oss-forbid-overwrite parameter is set to true, which specifies that existing objects cannot be overwritten by objects that have the same names.
"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 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,
// Specify the size of 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 {
const data = document.getElementById("file").files[0];
// Start the multipart upload task.
const res = await client.multipartUpload(name, data, {
...options,
// Configure an upload callback.
// If no callback server is required, delete the callback configurations.
callback: {
// Specify the address of the callback 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 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: {
// Specify custom parameters for the callback request.
var1: "value1",
var2: "value2",
},
},
});
console.log(res)
} catch (err) {
console.log(err);
}
});
</script>
</body>
</html>
using Aliyun.OSS;
// 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.
var endpoint = "yourEndpoint";
// 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.
var accessKeyId = "yourAccessKeyId";
var accessKeySecret = "yourAccessKeySecret";
// Specify the name of the bucket.
var bucketName = "examplebucket";
// Specify the full path of the object. Do not include the bucket name in the full path of the object.
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 object, the local object 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 object that you want to upload and the bucket to which you want to upload 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 part ETags. OSS verifies the validity of each part after it receives the part list. 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 multipart upload task.
fs.Seek(skipBytes, 0);
// Calculate the part size of 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 bucket name. 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();
// Specify the size of each part. Unit: bytes. Valid values: 100 KB to 5 GB.
int partCount = 100 * 1024;
// Start 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);
// Specify the part number of each part. The number starts from 1. Each part that you want 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);
// Implement upload callback. You can set the CALLBACK_SERVER parameter when you complete the multipart upload task. A callback request is sent to the specified server address after you complete the multipart upload task. You can view the server callback 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. Do not include the bucket name in the full path. Example: exampledir/exampleobject.txt. */
std::string ObjectName = "exampledir/exampleobject.txt";
/* Initialize resources, such as network resources. */
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;
return -1;
}
/* Release resources, such as network resources. */
ShutdownSdk();
return 0;
}
#include "oss_api.h"
#include "aos_http_io.h"
#include <sys/stat.h>
/* 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. */
const char *endpoint = "yourEndpoint";
/* 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. */
const char *access_key_id = "yourAccessKeyId";
const char *access_key_secret = "yourAccessKeySecret";
/* Specify the name of the bucket. Example: examplebucket. */
const char *bucket_name = "examplebucket";
/* Specify the full path of the object. Do not include the bucket name in the full path. Example: exampledir/exampleobject.txt. */
const char *object_name = "exampledir/exampleobject.txt";
/* Specify the full path of the local file. */
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 data of 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);
/* Specify whether to use CNAME to access OSS. A value of 0 indicates that CNAME is not used. */
options->config->is_cname = 0;
/* Configure network parameters, such as the timeout period. */
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 the aos_http_io_initialize method in main() to initialize global resources, such as network resources and memory resources. */
if (aos_http_io_initialize(NULL, 0) != AOSE_OK) {
exit(1);
}
/* Create a memory pool to manage memory. aos_pool_t is equivalent to apr_pool_t. The code that is used to create a memory pool is included in the APR library. */
aos_pool_t *pool;
/* Create a memory pool. The value of the second parameter is NULL. This value specifies that the pool does not inherit other memory pools. */
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 the memory resources in the memory pool to the options. */
oss_client_options = oss_request_options_create(pool);
/* Initialize oss_client_options. */
init_options(oss_client_options);
/* Initialize the 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;
/* Initiate a multipart upload task and obtain the 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 initiated. */
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 task 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. This operation releases the memory resources that are allocated for the request. */
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 RESTful APIs
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.
FAQ
How do I delete parts?
You can use one of the following methods to delete parts:
- Automatic deletion
You can configure lifecycle rules to automatically delete parts at a scheduled time. For more information, see Configure lifecycle rules to delete expired parts.
- Manual deletion
You can call the AbortMultipartUpload operation to cancel a multipart upload task and delete the parts. For more information, see AbortMultipartUpload.
Can I upload a local file that is encrypted and compressed?
Yes.
Are the uploaded parts overwritten when I re-upload parts after a multipart upload task is interrupted?
After a multipart upload task is interrupted, if you use the original upload ID to re-upload all parts, the uploaded parts with the same names are overwritten. If you use a new upload ID to re-upload all parts, the parts that are uploaded by using the original upload ID are retained.
What is an upload ID in multipart upload?
An upload ID uniquely identifies a multipart upload task. Part numbers identify the relative positions of parts that share the same upload ID.
How long is the upload ID valid during a multipart upload task?
The upload ID remains valid throughout the multipart upload process. If the upload is terminated or completed, the upload ID becomes invalid. If you want to perform another multipart upload task, you must reinitialize a multipart upload task and generate a new upload ID.
Does OSS support automatic combination of parts?
No, OSS does not support automatic combination of parts. You need to manually combine parts into a complete object by calling CompleteMultipartUpload.