すべてのプロダクト
Search
ドキュメントセンター

Object Storage Service:C++ SDK を使用したオブジェクトのコピー

最終更新日:Nov 30, 2025

このトピックでは、同一リージョン内のバケット内、またはバケット間でオブジェクトをコピーする方法について説明します。

注意事項

  • このトピックでは、中国 (杭州) リージョンのパブリックエンドポイントを使用します。OSS と同じリージョンにある他の Alibaba Cloud サービスから OSS にアクセスする場合は、内部エンドポイントを使用してください。OSS のリージョンとエンドポイントの詳細については、「リージョンとエンドポイント」をご参照ください。

  • このトピックでは、OSS エンドポイントを使用して OSSClient インスタンスを作成します。カスタムドメイン名または Security Token Service (STS) を使用して OSSClient を作成する場合は、「OssClient インスタンスの作成」をご参照ください。

  • オブジェクトをコピーするには、ソースオブジェクトに対する読み取り権限と、宛先バケットに対する読み取りおよび書き込み権限が必要です。

  • ソースバケットと宛先バケットに保持ポリシーが設定されていないことを確認してください。設定されている場合、エラーメッセージ The object you specified is immutable. が返されます。

  • ソースバケットと宛先バケットは、同じリージョンにある必要があります。たとえば、中国 (杭州) リージョンにあるバケット内のオブジェクトを、中国 (青島) リージョンにある別のバケットにコピーすることはできません。

スモールオブジェクトのコピー

client.CopyObject を呼び出すことで、サイズが 1 GB 未満のオブジェクトを、同一リージョン内のソースバケットから宛先バケットにコピーできます。次の表に、client.CopyObject を呼び出す際のパラメーター設定について説明します。

設定メソッド

説明

CopyObjectOutcome OssClient::CopyObject(const CopyObjectRequest &request)

宛先オブジェクトのメタデータとコピー条件を指定できます。ソースオブジェクトと宛先オブジェクトの URL が同じ場合、リクエストで指定されたメタデータがソースオブジェクトのメタデータを置き換えます。

次のコードは、スモールオブジェクトをコピーする方法の例です。

#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* OSS へのアクセスに使用するアカウント情報を初期化します。*/
    
    /* バケットが配置されているリージョンのエンドポイントを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントを https://oss-cn-hangzhou.aliyuncs.com に設定します。*/
    std::string Endpoint = "yourEndpoint";
    /* バケットが配置されているリージョンを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合、リージョンを cn-hangzhou に設定します。*/
    std::string Region = "yourRegion";
    /* ソースバケットの名前を指定します。例:srcexamplebucket。*/
    std::string SourceBucketName = "srcexamplebucket";
    /* 宛先バケットの名前を指定します。宛先バケットはソースバケットと同じリージョンにある必要があります。例:destbucket。*/
    std::string CopyBucketName = "destbucket";
    /* ソースオブジェクトの完全なパスを指定します。バケット名は完全なパスに含めないでください。例:srcdir/scrobject.txt。*/
    std::string SourceObjectName = "srcdir/scrobject.txt";
    /* 宛先オブジェクトの完全なパスを指定します。バケット名は完全なパスに含めないでください。例:destdir/destobject.txt。*/
    std::string CopyObjectName = "destdir/destobject.txt";

    /* ネットワークリソースなどのリソースを初期化します。*/
    InitializeSdk();

    ClientConfiguration conf;
    conf.signatureVersion = SignatureVersionType::V4;
    /* 環境変数からアクセス認証情報を取得します。サンプルコードを実行する前に、OSS_ACCESS_KEY_ID および 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;
    }

    /* ネットワークリソースなどのリソースを解放します。*/
    ShutdownSdk();
    return 0;
}

ラージオブジェクトのコピー

サイズが 1 GB を超えるオブジェクトをコピーするには、オブジェクトをパートに分割し、UploadPartCopy を使用してパートを順次コピーする必要があります。マルチパートコピーを実装するには、次の手順を実行します。

  1. client.InitiateMultipartUpload を使用して、マルチパートコピータスクを開始します。

  2. client.UploadPartCopy を使用してパートをコピーします。最後のパートを除き、すべてのパートは 100 KB より大きい必要があります。

  3. client.CompleteMultipartUpload を使用して、マルチパートコピータスクを完了します。

次のコードは、ラージオブジェクトをコピーする方法の例です。

#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* OSS へのアクセスに使用するアカウント情報を初期化します。*/    
            
    /* バケットが配置されているリージョンのエンドポイントを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントを https://oss-cn-hangzhou.aliyuncs.com に設定します。*/
    std::string Endpoint = "yourEndpoint";
    /* バケットが配置されているリージョンを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合、リージョンを cn-hangzhou に設定します。*/
    std::string Region = "yourRegion";
    /* ソースバケットの名前を指定します。例:srcexamplebucket。*/
    std::string SourceBucketName = "srcexamplebucket";
    /* 宛先バケットの名前を指定します。宛先バケットはソースバケットと同じリージョンにある必要があります。例:destbucket。*/
    std::string CopyBucketName = "destbucket";
    /* ソースオブジェクトの完全なパスを指定します。バケット名は完全なパスに含めないでください。例:srcdir/scrobject.txt。*/
    std::string SourceObjectName = "srcdir/scrobject.txt";
    /* 宛先オブジェクトの完全なパスを指定します。バケット名は完全なパスに含めないでください。例:destdir/destobject.txt。*/
    std::string CopyObjectName = "destdir/destobject.txt";

    /* ネットワークリソースなどのリソースを初期化します。*/
    InitializeSdk();

    ClientConfiguration conf;
    conf.signatureVersion = SignatureVersionType::V4;
    /* 環境変数からアクセス認証情報を取得します。サンプルコードを実行する前に、OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET 環境変数が設定されていることを確認してください。*/
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);
    client.SetRegion(Region);

    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();

    /* ラージオブジェクトをコピーします。*/
    InitiateMultipartUploadRequest initUploadRequest(CopyBucketName, CopyObjectName);

    /* マルチパートコピータスクを開始します。*/
    auto uploadIdResult = client.InitiateMultipartUpload(initUploadRequest);
    auto uploadId = uploadIdResult.result().UploadId();
    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;
        }

    }

    /* マルチパートコピータスクを完了します。*/
    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;
    }

    /* ネットワークリソースなどのリソースを解放します。*/
    ShutdownSdk();
    return 0;
}

関連ドキュメント

  • スモールオブジェクトとラージオブジェクトのコピーに使用される完全なサンプルコードについては、GitHub をご参照ください。

  • スモールオブジェクトをコピーするために呼び出すことができる API 操作の詳細については、「CopyObject」をご参照ください。

  • ラージオブジェクトをコピーするために呼び出すことができる API 操作の詳細については、「UploadPartCopy」をご参照ください。