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

Object Storage Service:オブジェクトのコピー

最終更新日:Dec 19, 2023

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

使用上の注意

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

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

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

  • ソースバケットとターゲットバケットに保持ポリシーが設定されていないことを確認します。 それ以外の場合、エラーメッセージ指定したオブジェクトは不変です。 が返されます。

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

小さなオブジェクトをコピーする

client.CopyObjectを呼び出して、1 GB未満のオブジェクトをソースバケットから同じリージョン内の宛先バケットにコピーできます。 client.CopyObjectを呼び出すときにパラメーターを設定する方法を次の表に示します。

設定方法

説明

CopyObjectOutcome OssClient::CopyObject(const CopyObjectRequest &request)

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

次のコードは、小さなオブジェクトをコピーする方法の例を示しています。

#include <alibabacloud/oss/OssClient.h>
名前空間listaCloud::OSSを使用します。int main(void)
{
    /* OSSへのアクセスに使用されるアカウントに関する情報を初期化します。 */
    
    /* バケットが配置されているリージョンのエンドポイントを指定します。 たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントをhttps://oss-cn-hangzhou.aliyuncs.comに設定します。 */
    std::stringエンドポイント="https://oss-cn-hangzhou.aliyuncs.com";
    /* ソースバケットの名前を指定します。 例: 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;
    /* 環境変数からアクセス資格情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_IDおよびOSS_ACCESS_KEY_SECRET環境変数が設定されていることを確認してください。 */
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClientクライアント (Endpoint, credentialsProvider, conf);

    CopyObjectRequestリクエスト (CopyBucketName, CopyObjectName);
    request.setCopySource(SourceBucketName, SourceObjectName);

    /* オブジェクトをコピーします。 */
    auto outcome = client.CopyObject (リクエスト);

    if (!outcome.isSuccess()) {
        /* 例外を処理します。 */
        std::cout << "CopyObject fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        return -1;
    }

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

大きなオブジェクトをコピーする

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

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

  2. client.UploadPartCopyを使用して部品をコピーします。 最後の部分を除いて、すべての部分は100 KBより大きくなければなりません。

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

次のコードは、ラージオブジェクトをコピーする方法の例を示しています。

#include <alibabacloud/oss/OssClient.h>
名前空間listaCloud::OSSを使用します。int main(void)
{
    /* OSSへのアクセスに使用されるアカウントに関する情報を初期化します。 */    
            
    /* バケットが配置されているリージョンのエンドポイントを指定します。 たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントをhttps://oss-cn-hangzhou.aliyuncs.comに設定します。 */
    std::stringエンドポイント="https://oss-cn-hangzhou.aliyuncs.com";
    /* ソースバケットの名前を指定します。 例: 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;
    /* 環境変数からアクセス資格情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_IDおよびOSS_ACCESS_KEY_SECRET環境変数が設定されていることを確認してください。 */
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClientクライアント (Endpoint, credentialsProvider, conf);

    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()) {
            パートパート (i, uploadPartOutcome.result().ETag());
            partETagList.push_back (部品);
        }
        else {
            std::cout << "UploadPartCopy fail" <<
            ",code:" << uploadPartOutcome.error().Code() <<<
            ",message:" << uploadPartOutcome.error().Message() <<
            ",requestId:" << uploadPartOutcome.error().RequestId() << std::endl;
        }

    }

    /* マルチパートコピータスクを完了します。 */
    CompleteMultipartUploadRequestリクエスト (CopyBucketName、CopyObjectName、partETagList、uploadId);
    auto outcome = client.CompleteMultipartUpload (リクエスト);

    if (!outcome.isSuccess()) {
        /* 例外を処理します。 */
        std::cout << "CompleteMultipartUpload fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        return -1;
    }

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

参考資料

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

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

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