All Products
Search
Document Center

Object Storage Service:Copy objects by using the C++ SDK

Last Updated:Mar 20, 2026

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 sizeMethodAPI
Smaller than 1 GBSimple copyCopyObject
Larger than 1 GBMultipart copyInitiateMultipartUploadUploadPartCopyCompleteMultipartUpload

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:

  1. Call InitiateMultipartUpload to start a multipart copy task and get an upload ID.

  2. Call UploadPartCopy in a loop to copy each part. Collect the ETag returned for each part.

  3. Call CompleteMultipartUpload with 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