Use the OSS C++ SDK to copy an object within a bucket or across buckets in the same region.
Choose a copy method
Choose a method based on object size:
| Object size | Method | API |
|---|---|---|
| Smaller than 1 GB | Simple copy | CopyObject |
| Larger than 1 GB | Multipart copy | InitiateMultipartUpload → UploadPartCopy → CompleteMultipartUpload |
Prerequisites
Before you begin, make sure that you have:
Read permissions on the source object
Read and write permissions on the destination bucket
Source and destination buckets in the same region (objects in China (Hangzhou) cannot be copied to China (Qingdao), for example)
No retention policies on either bucket — if a retention policy exists, the operation returns
The object you specified is immutable.
These examples use the public endpoint for the China (Hangzhou) region. To access OSS from other Alibaba Cloud services in the same region, use an internal endpoint. To create an OSSClient instance using a custom domain name or Security Token Service (STS), see Create an OSSClient instance.Copy a small object
CopyObject copies an object smaller than 1 GB in a single request. If the source and destination paths are identical, the metadata specified in the request replaces the existing object metadata.
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;
int main(void)
{
/* Specify the endpoint for the region where the bucket is located.
Example: https://oss-cn-hangzhou.aliyuncs.com for China (Hangzhou). */
std::string Endpoint = "yourEndpoint";
/* Specify the region ID. Example: cn-hangzhou. */
std::string Region = "yourRegion";
/* Source bucket name. Example: srcexamplebucket. */
std::string SourceBucketName = "srcexamplebucket";
/* Destination bucket name. Must be in the same region as the source bucket. Example: destbucket. */
std::string CopyBucketName = "destbucket";
/* Full path of the source object, excluding the bucket name. Example: srcdir/scrobject.txt. */
std::string SourceObjectName = "srcdir/scrobject.txt";
/* Full path of the destination object, excluding the bucket name. Example: destdir/destobject.txt. */
std::string CopyObjectName = "destdir/destobject.txt";
/* Initialize SDK resources. */
InitializeSdk();
ClientConfiguration conf;
conf.signatureVersion = SignatureVersionType::V4;
/* Load credentials from environment variables OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET. */
auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
OssClient client(Endpoint, credentialsProvider, conf);
client.SetRegion(Region);
CopyObjectRequest request(CopyBucketName, CopyObjectName);
request.setCopySource(SourceBucketName, SourceObjectName);
auto outcome = client.CopyObject(request);
if (!outcome.isSuccess()) {
std::cout << "CopyObject fail"
<< ", code:" << outcome.error().Code()
<< ", message:" << outcome.error().Message()
<< ", requestId:" << outcome.error().RequestId() << std::endl;
return -1;
}
/* Release SDK resources. */
ShutdownSdk();
return 0;
}Copy a large object
For objects larger than 1 GB, split the object into parts and copy each part using UploadPartCopy. All parts except the last must be larger than 100 KB.
The process has three steps:
Call
InitiateMultipartUploadto start a multipart copy task and get an upload ID.Call
UploadPartCopyin a loop to copy each part. Collect the ETag returned for each part.Call
CompleteMultipartUploadwith the collected ETags to assemble the final object.
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;
int main(void)
{
/* Specify the endpoint for the region where the bucket is located.
Example: https://oss-cn-hangzhou.aliyuncs.com for China (Hangzhou). */
std::string Endpoint = "yourEndpoint";
/* Specify the region ID. Example: cn-hangzhou. */
std::string Region = "yourRegion";
/* Source bucket name. Example: srcexamplebucket. */
std::string SourceBucketName = "srcexamplebucket";
/* Destination bucket name. Must be in the same region as the source bucket. Example: destbucket. */
std::string CopyBucketName = "destbucket";
/* Full path of the source object, excluding the bucket name. Example: srcdir/scrobject.txt. */
std::string SourceObjectName = "srcdir/scrobject.txt";
/* Full path of the destination object, excluding the bucket name. Example: destdir/destobject.txt. */
std::string CopyObjectName = "destdir/destobject.txt";
/* Initialize SDK resources. */
InitializeSdk();
ClientConfiguration conf;
conf.signatureVersion = SignatureVersionType::V4;
/* Load credentials from environment variables OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET. */
auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
OssClient client(Endpoint, credentialsProvider, conf);
client.SetRegion(Region);
/* Get the source object size. */
auto getObjectMetaReq = GetObjectMetaRequest(SourceBucketName, SourceObjectName);
auto getObjectMetaResult = client.GetObjectMeta(getObjectMetaReq);
if (!getObjectMetaResult.isSuccess()) {
std::cout << "GetObjectMeta fail"
<< ", code:" << getObjectMetaResult.error().Code()
<< ", message:" << getObjectMetaResult.error().Message()
<< ", requestId:" << getObjectMetaResult.error().RequestId() << std::endl;
return -1;
}
auto objectSize = getObjectMetaResult.result().ContentLength();
/* Step 1: Start the multipart copy task. */
InitiateMultipartUploadRequest initUploadRequest(CopyBucketName, CopyObjectName);
auto uploadIdResult = client.InitiateMultipartUpload(initUploadRequest);
auto uploadId = uploadIdResult.result().UploadId();
/* Step 2: Copy parts. Each part (except the last) must be larger than 100 KB. */
int64_t partSize = 100 * 1024;
PartList partETagList;
int partCount = static_cast<int>(objectSize / partSize);
if (objectSize % partSize != 0) {
partCount++;
}
for (int i = 1; i <= partCount; i++) {
auto skipBytes = partSize * (i - 1);
auto size = (partSize < objectSize - skipBytes) ? partSize : (objectSize - skipBytes);
auto uploadPartCopyReq = UploadPartCopyRequest(
CopyBucketName, CopyObjectName,
SourceBucketName, SourceObjectName,
uploadId, i);
uploadPartCopyReq.setCopySourceRange(skipBytes, skipBytes + size - 1);
auto uploadPartOutcome = client.UploadPartCopy(uploadPartCopyReq);
if (uploadPartOutcome.isSuccess()) {
Part part(i, uploadPartOutcome.result().ETag());
partETagList.push_back(part);
} else {
std::cout << "UploadPartCopy fail"
<< ", code:" << uploadPartOutcome.error().Code()
<< ", message:" << uploadPartOutcome.error().Message()
<< ", requestId:" << uploadPartOutcome.error().RequestId() << std::endl;
}
}
/* Step 3: Complete the multipart copy task. */
CompleteMultipartUploadRequest request(CopyBucketName, CopyObjectName, partETagList, uploadId);
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 SDK resources. */
ShutdownSdk();
return 0;
}What's next
Complete sample code: GitHub
CopyObject API reference: CopyObject
UploadPartCopy API reference: UploadPartCopy