Multipart upload splits a large object into smaller parts, uploads each part independently, and combines them into a single object by calling CompleteMultipartUpload. Use multipart upload for large objects to get:
Resumable uploads — resume an interrupted upload without restarting from scratch
Fault tolerance — a network error only affects the current part, not the entire upload
Prerequisites
Before you begin, ensure that you have:
The
oss:PutObjectpermission (required forInitiateMultipartUpload,UploadPart, andCompleteMultipartUpload)The
OSS_ACCESS_KEY_IDandOSS_ACCESS_KEY_SECRETenvironment variables set with valid credentialsThe OSS C++ SDK installed and initialized
For endpoint configuration and OSSClient setup options, see Regions and endpoints and Create an OSSClient instance.
How it works
A multipart upload consists of three steps:
Initiate — call
InitiateMultipartUploadto get a globally unique upload ID from OSS.Upload parts — call
UploadPartfor each part, using the upload ID to associate parts with the same upload.Complete — call
CompleteMultipartUploadwith the ETag of every uploaded part. OSS verifies each part and assembles the final object.
Part constraints:
| Constraint | Value |
|---|---|
| Minimum part size | 100 KB |
| Maximum part size | 5 GB |
| Last part minimum size | No minimum (can be less than 100 KB) |
Part numbering: if you upload new data using the same part number, OSS overwrites the existing part data for that number.
Data integrity: OSS computes the MD5 hash of each received part and returns it in the response ETag header. The SDK computes its own MD5 hash and compares it with OSS's value. A mismatch returns the InvalidDigest error code.
Upload a large object
The following example shows a complete multipart upload that reads a local file, splits it into 100 KB parts, and uploads each part sequentially.
All examples use SignatureVersionType::V4 and load credentials from environment variables.
#include <alibabacloud/oss/OssClient.h>
#include <fstream>
// Returns the size of a local file in bytes.
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)
{
// Replace the placeholders below with your actual values.
// Endpoint example: https://oss-cn-hangzhou.aliyuncs.com (China (Hangzhou) public endpoint)
std::string Endpoint = "yourEndpoint";
// Region example: cn-hangzhou
std::string Region = "yourRegion";
std::string BucketName = "examplebucket";
// Full object path, excluding the bucket name. Example: exampledir/exampleobject.txt
std::string ObjectName = "exampledir/exampleobject.txt";
// Initialize network resources.
InitializeSdk();
ClientConfiguration conf;
conf.signatureVersion = SignatureVersionType::V4;
// Load credentials from OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables.
auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
OssClient client(Endpoint, credentialsProvider, conf);
client.SetRegion(Region);
// Step 1: Initiate the multipart upload to get an upload ID.
InitiateMultipartUploadRequest initUploadRequest(BucketName, ObjectName);
// (Optional) Set the storage class:
// initUploadRequest.MetaData().addHeader("x-oss-storage-class", "Standard");
auto uploadIdResult = client.InitiateMultipartUpload(initUploadRequest);
auto uploadId = uploadIdResult.result().UploadId();
// Save the upload ID if you need to cancel the upload or list uploaded parts later.
// Step 2: Upload each part.
// Part size: minimum 100 KB, maximum 5 GB. The last part can be smaller than 100 KB.
std::string fileToUpload = "yourLocalFilename";
int64_t partSize = 100 * 1024;
PartList partETagList;
auto fileSize = getFileSize(fileToUpload);
int partCount = static_cast<int>(fileSize / partSize);
if (fileSize % partSize != 0) {
partCount++;
}
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()) {
// Save the ETag returned for each part — required to complete the upload.
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;
}
}
// Step 3: Complete the multipart upload.
// Provide all part ETags. OSS verifies each part and assembles the final object.
CompleteMultipartUploadRequest request(BucketName, ObjectName);
request.setUploadId(uploadId);
request.setPartList(partETagList);
// (Optional) Set the access control list (ACL):
// request.setAcl(CannedAccessControlList::Private);
auto outcome = client.CompleteMultipartUpload(request);
if (!outcome.isSuccess()) {
std::cout << "CompleteMultipartUpload fail"
<< ", code:" << outcome.error().Code()
<< ", message:" << outcome.error().Message()
<< ", requestId:" << outcome.error().RequestId() << std::endl;
return -1;
}
// Release network resources.
ShutdownSdk();
return 0;
}Getting part ETags: CompleteMultipartUpload requires the ETag of every uploaded part. Get ETags in one of two ways:
From the upload response — the code above saves the ETag from each
UploadPartresponse.By calling
ListParts— query all uploaded parts for a given upload ID.
List uploaded parts
Call ListParts to list all successfully uploaded parts for a given upload ID. By default, up to 1,000 parts are returned per request. If your upload has more than 1,000 parts, retrieve them by page.
List parts (default limit)
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;
int main(void)
{
std::string Endpoint = "yourEndpoint";
std::string Region = "yourRegion";
std::string BucketName = "examplebucket";
std::string ObjectName = "exampledir/exampleobject.txt";
// Upload ID obtained from InitiateMultipartUpload.
std::string UploadId = "yourUploadId";
InitializeSdk();
ClientConfiguration conf;
conf.signatureVersion = SignatureVersionType::V4;
auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
OssClient client(Endpoint, credentialsProvider, conf);
client.SetRegion(Region);
// List up to 1,000 uploaded parts (default).
ListPartsRequest listuploadrequest(BucketName, ObjectName);
listuploadrequest.setUploadId(UploadId);
bool IsTruncated = false;
do {
auto listUploadResult = client.ListParts(listuploadrequest);
if (!listUploadResult.isSuccess()) {
std::cout << "ListParts fail"
<< ", code:" << listUploadResult.error().Code()
<< ", message:" << listUploadResult.error().Message()
<< ", requestId:" << listUploadResult.error().RequestId() << std::endl;
break;
}
for (const auto& part : listUploadResult.result().PartList()) {
std::cout << "part"
<< ", name:" << part.PartNumber()
<< ", size:" << part.Size()
<< ", etag:" << part.ETag()
<< ", lastmodify time:" << part.LastModified() << std::endl;
}
listuploadrequest.setPartNumberMarker(listUploadResult.result().NextPartNumberMarker());
IsTruncated = listUploadResult.result().IsTruncated();
} while (IsTruncated);
ShutdownSdk();
return 0;
}List parts by page
To control page size, set setMaxParts() and use NextPartNumberMarker to fetch the next page.
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;
int main(void)
{
std::string Endpoint = "yourEndpoint";
std::string Region = "yourRegion";
std::string BucketName = "examplebucket";
std::string ObjectName = "exampledir/exampleobject.txt";
std::string UploadId = "yourUploadId";
InitializeSdk();
ClientConfiguration conf;
conf.signatureVersion = SignatureVersionType::V4;
auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
OssClient client(Endpoint, credentialsProvider, conf);
client.SetRegion(Region);
ListPartsRequest listuploadrequest(BucketName, ObjectName);
listuploadrequest.setUploadId(UploadId);
listuploadrequest.setMaxParts(50); // Return 50 parts per page.
bool IsTruncated = false;
do {
auto listuploadresult = client.ListParts(listuploadrequest);
if (!listuploadresult.isSuccess()) {
std::cout << "ListParts fail"
<< ", code:" << listuploadresult.error().Code()
<< ", message:" << listuploadresult.error().Message()
<< ", requestId:" << listuploadresult.error().RequestId() << std::endl;
break;
}
for (const auto& part : listuploadresult.result().PartList()) {
std::cout << "part"
<< ", name:" << part.PartNumber()
<< ", size:" << part.Size()
<< ", etag:" << part.ETag()
<< ", lastmodify time:" << part.LastModified() << std::endl;
}
listuploadrequest.setPartNumberMarker(listuploadresult.result().NextPartNumberMarker());
IsTruncated = listuploadresult.result().IsTruncated();
} while (IsTruncated);
ShutdownSdk();
return 0;
}List multipart upload events
Call ListMultipartUploads to list all in-progress multipart upload events — those that have been initiated but not yet completed or canceled. By default, up to 1,000 events are returned per request.
List upload events (default limit)
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;
int main(void)
{
std::string Endpoint = "yourEndpoint";
std::string Region = "yourRegion";
std::string BucketName = "examplebucket";
InitializeSdk();
ClientConfiguration conf;
conf.signatureVersion = SignatureVersionType::V4;
auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
OssClient client(Endpoint, credentialsProvider, conf);
client.SetRegion(Region);
// List up to 1,000 in-progress upload events (default).
ListMultipartUploadsRequest listmultiuploadrequest(BucketName);
bool IsTruncated = false;
do {
auto listresult = client.ListMultipartUploads(listmultiuploadrequest);
if (!listresult.isSuccess()) {
std::cout << "ListMultipartUploads fail"
<< ", code:" << listresult.error().Code()
<< ", message:" << listresult.error().Message()
<< ", requestId:" << listresult.error().RequestId() << std::endl;
break;
}
for (const auto& part : listresult.result().MultipartUploadList()) {
std::cout << "part"
<< ", name:" << part.Key
<< ", uploadid:" << part.UploadId
<< ", initiated time:" << part.Initiated << std::endl;
}
listmultiuploadrequest.setKeyMarker(listresult.result().NextKeyMarker());
listmultiuploadrequest.setUploadIdMarker(listresult.result().NextUploadIdMarker());
IsTruncated = listresult.result().IsTruncated();
} while (IsTruncated);
ShutdownSdk();
return 0;
}List upload events by page
To control page size, set setMaxUploads() and use NextKeyMarker and NextUploadIdMarker to fetch the next page.
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;
int main(void)
{
std::string Endpoint = "yourEndpoint";
std::string Region = "yourRegion";
std::string BucketName = "examplebucket";
InitializeSdk();
ClientConfiguration conf;
conf.signatureVersion = SignatureVersionType::V4;
auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
OssClient client(Endpoint, credentialsProvider, conf);
client.SetRegion(Region);
ListMultipartUploadsRequest listmultiuploadrequest(BucketName);
listmultiuploadrequest.setMaxUploads(50); // Return 50 events per page.
bool IsTruncated = false;
do {
auto listresult = client.ListMultipartUploads(listmultiuploadrequest);
if (!listresult.isSuccess()) {
std::cout << "ListMultipartUploads fail"
<< ", code:" << listresult.error().Code()
<< ", message:" << listresult.error().Message()
<< ", requestId:" << listresult.error().RequestId() << std::endl;
break;
}
for (const auto& part : listresult.result().MultipartUploadList()) {
std::cout << "part"
<< ", name:" << part.Key
<< ", uploadid:" << part.UploadId
<< ", initiated time:" << part.Initiated << std::endl;
}
listmultiuploadrequest.setKeyMarker(listresult.result().NextKeyMarker());
listmultiuploadrequest.setUploadIdMarker(listresult.result().NextUploadIdMarker());
IsTruncated = listresult.result().IsTruncated();
} while (IsTruncated);
ShutdownSdk();
return 0;
}Cancel a multipart upload
Call AbortMultipartUpload to cancel an in-progress upload. After cancellation, the upload ID becomes invalid and all uploaded parts are deleted.
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;
int main(void)
{
std::string Endpoint = "yourEndpoint";
std::string Region = "yourRegion";
std::string BucketName = "examplebucket";
std::string ObjectName = "exampledir/exampleobject.txt";
// Upload ID obtained from InitiateMultipartUpload.
std::string UploadId = "yourUploadId";
InitializeSdk();
ClientConfiguration conf;
conf.signatureVersion = SignatureVersionType::V4;
auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
OssClient client(Endpoint, credentialsProvider, conf);
client.SetRegion(Region);
// Initiate a multipart upload to get an upload ID (if you don't already have one).
InitiateMultipartUploadRequest initUploadRequest(BucketName, ObjectName);
auto uploadIdResult = client.InitiateMultipartUpload(initUploadRequest);
auto uploadId = uploadIdResult.result().UploadId();
// Cancel the multipart upload. All uploaded parts are deleted.
AbortMultipartUploadRequest abortUploadRequest(BucketName, ObjectName, uploadId);
auto outcome = client.AbortMultipartUpload(abortUploadRequest);
if (!outcome.isSuccess()) {
std::cout << "AbortMultipartUpload fail"
<< ", code:" << outcome.error().Code()
<< ", message:" << outcome.error().Message()
<< ", requestId:" << outcome.error().RequestId() << std::endl;
return -1;
}
ShutdownSdk();
return 0;
}References
Complete sample code: GitHub example
API reference: