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

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

最終更新日:Feb 20, 2025

このトピックでは、Object Storage Service (OSS) のバージョン管理が有効になっているバケット内のオブジェクトをコピーする方法について説明します。CopyObject を呼び出して最大 1 GB のオブジェクトをコピーし、UploadPartCopy を呼び出して 1 GB を超えるオブジェクトをコピーできます。

使用上の注意

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

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

  • オブジェクトをコピーするには、oss:GetObject および oss:PutObject 権限が必要です。詳細については、「RAM ユーザーへのカスタムポリシーのアタッチ」をご参照ください。

小さなオブジェクトのコピー

CopyObject を呼び出して、同じリージョン内のソースバケットからデスティネーションバケットに最大 1 GB のオブジェクトをコピーできます。

  • デフォルトでは、x-oss-copy-source ヘッダーは、コピーするオブジェクトの現在のバージョンを指定します。オブジェクトの現在のバージョンが削除マーカーの場合、OSS は HTTP 404 ステータスコードを返します。HTTP ステータスコードは、オブジェクトが存在しないことを示します。指定したオブジェクトバージョンをコピーするために、versionId を x-oss-copy-source リクエストヘッダーに追加できます。削除マーカーはコピーできません。

  • オブジェクトの以前のバージョンを同じバケットにコピーできます。コピーされた以前のバージョンは、オブジェクトの現在のバージョンになります。このようにして、オブジェクトの以前のバージョンが復元されます。

  • デスティネーションバケットでバージョン管理が有効になっている場合、OSS はデスティネーションオブジェクトに一意のバージョン ID を生成します。バージョン ID は、レスポンスの x-oss-version-id ヘッダーの値として返されます。デスティネーションバケットでバージョン管理が無効になっているか一時停止されている場合、OSS は ID が null のバージョンをデスティネーションオブジェクトに生成し、ID が null の元のバージョンを上書きします。

  • 追加可能なオブジェクトは、バージョン管理が有効になっているか一時停止されているデスティネーションバケットにコピーできません。

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

using Aliyun.OSS;
using Aliyun.OSS.Common;
// バケットが配置されているリージョンのエンドポイントを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合は、エンドポイントを https://oss-cn-hangzhou.aliyuncs.com に設定します。
var endpoint = "yourEndpoint";
// 環境変数からアクセス認証情報を取得します。サンプルコードを実行する前に、OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET 環境変数が構成されていることを確認してください。
var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID");
var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET");
// ソースバケットの名前を指定します。
var sourceBucket = "yourSourceBucketName";
// ソースオブジェクトの完全なパスを指定します。完全なパスにバケット名を含めないでください。
var sourceObject = "yourSourceObjectName";
// デスティネーションバケットの名前を指定します。デスティネーションバケットは、ソースバケットと同じリージョンに配置する必要があります。
var targetBucket = "yourDestBucketName";
// デスティネーションオブジェクトの完全なパスを指定します。完全なパスにバケット名を含めないでください。
var targetObject = "yourDestObjectName";
// ソースオブジェクトのバージョン ID を指定します。
var versionid = "yourArchiveObjectVersionid";
// バケットが配置されているリージョンを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合は、リージョンを cn-hangzhou に設定します。
const string region = "cn-hangzhou";

// ClientConfiguration インスタンスを作成し、要件に基づいてデフォルトパラメータを変更します。
var conf = new ClientConfiguration();

// 署名アルゴリズム V4 を使用します。
conf.SignatureVersion = SignatureVersion.V4;

// OSSClient インスタンスを作成します。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret, conf);
client.SetRegion(region);
try
{
    var metadata = new ObjectMetadata();
    metadata.AddHeader("mk1", "mv1");
    metadata.AddHeader("mk2", "mv2");
    var req = new CopyObjectRequest(sourceBucket, sourceObject, targetBucket, targetObject)
    {
        // NewObjectMetadata の値が null の場合、COPY モードが使用され、ソースオブジェクトのメタデータがデスティネーションオブジェクトにコピーされます。NewObjectMetadata の値が null でない場合、REPLACE モードが使用され、ソースオブジェクトのメタデータがデスティネーションオブジェクトのメタデータを上書きします。
        NewObjectMetadata = metadata,
        // オブジェクトのバージョン ID を指定します。
        SourceVersionId = versionid
    };
    // オブジェクトをコピーします。
    var result = client.CopyObject(req);
    Console.WriteLine("Copy object succeeded, vesionid:{0}", result.VersionId);
}
catch (OssException ex)
{
    Console.WriteLine("Failed with error code: {0}; Error info: {1}. \nRequestID: {2} \tHostID: {3}",
        ex.ErrorCode, ex.Message, ex.RequestId, ex.HostId);
}
catch (Exception ex)
{
    Console.WriteLine("Failed with error info: {0}", ex.Message);
}

大きなオブジェクトのコピー

1 GB を超えるオブジェクトをコピーするには、オブジェクトをパーツに分割し、UploadPartCopy を使用してパーツをコピーする必要があります。

デフォルトでは、UploadPartCopy 操作は、指定されたオブジェクトの現在のバージョンからデータをコピーすることによってパーツをアップロードします。オブジェクトの指定されたバージョンをコピーするために、バージョン ID を x-oss-copy-source ヘッダーに追加できます。例: x-oss-copy-source: /SourceBucketName/SourceObjectName?versionId=CAEQMxiBgICAof2D0BYiIDJhMGE3N2M1YTI1NDQzOGY5NTkyNTI3MGYyMzJm****。

説明

SourceObjectName パラメータの値は URL エンコードする必要があります。コピーされたオブジェクトのバージョン ID は、レスポンスの x-oss-copy-source-version-id ヘッダーの値として返されます。

リクエストでバージョン ID が指定されておらず、ソースオブジェクトの現在のバージョンが削除マーカーの場合、OSS は 404 Not Found を返します。リクエストでバージョン ID が指定されており、ソースオブジェクトの指定されたバージョンが削除マーカーの場合、OSS は 400 Bad Request を返します。

次のサンプルコードは、マルチパートコピーを使用して大きなオブジェクトをコピーする方法の例を示しています。

using System;
using System.Collections.Generic;
using Aliyun.OSS;
using Aliyun.OSS.Common;

namespace Samples
{
    public class Program
    {
        public static void Main(string[] args)
        {
            // バケットが配置されているリージョンのエンドポイントを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合は、エンドポイントを https://oss-cn-hangzhou.aliyuncs.com に設定します。
            var endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
            // 環境変数からアクセス認証情報を取得します。サンプルコードを実行する前に、OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET 環境変数が構成されていることを確認してください。
            var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID");
            var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET");
            // ソースバケットの名前を指定します。
            var sourceBucket = "yourSourceBucketName";
            // ソースオブジェクトの完全なパスを指定します。完全なパスにバケット名を含めないでください。
            var sourceObject = "yourSourceObjectName";
            // デスティネーションバケットの名前を指定します。デスティネーションバケットは、ソースバケットと同じリージョンに配置する必要があります。
            var targetBucket = "yourDestBucketName";
            // デスティネーションオブジェクトの完全なパスを指定します。完全なパスにバケット名を含めないでください。
            var targetObject = "yourDestObjectName";
            // ソースオブジェクトのバージョン ID を指定します。
            var sourceObjectVersionid = "yourSourceObjectVersionid";
            var partSize = 50 * 1024 * 1024;
            // OSSClient インスタンスを作成します。
            var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
            try
            {
                // マルチパートコピータスクを開始します。InitiateMultipartUploadRequest 操作を呼び出して、デスティネーションオブジェクトのメタデータを指定できます。
                var initRequest = new InitiateMultipartUploadRequest(targetBucket, targetObject);
                var result = client.InitiateMultipartUpload(initRequest);
                // アップロード ID を表示します。
                var uploadId = result.UploadId;
                Console.WriteLine("Init multipart upload succeeded, Upload Id: {0}", result.UploadId);
                // パーツの総数を計算します。
                var request = new GetObjectMetadataRequest(sourceBucket, sourceObject)
                {
                    // オブジェクトのバージョン ID を指定します。
                    VersionId = sourceObjectVersionid
                };
                var metadata = client.GetObjectMetadata(request);
                var fileSize = metadata.ContentLength;
                var partCount = (int)fileSize / partSize;
                if (fileSize % partSize != 0)
                {
                    partCount++;
                }
                // マルチパートコピータスクを開始します。
                var partETags = new List<PartETag>();
                for (var i = 0; i < partCount; i++)
                {
                    var skipBytes = (long)partSize * i;
                    var size = (partSize < fileSize - skipBytes) ? partSize : (fileSize - skipBytes);
                    // UploadPartCopyRequest リクエストを作成します。UploadPartCopyRequest 操作を呼び出して、条件を指定できます。
                    var uploadPartCopyRequest = new UploadPartCopyRequest(targetBucket, targetObject, sourceBucket, sourceObject, uploadId)
                    {
                        PartSize = size,
                        PartNumber = i + 1,
                        // BeginIndex を使用して、パーツをアップロードする開始位置を見つけます。
                        BeginIndex = skipBytes,
                        // オブジェクトのバージョン ID を指定します。
                        VersionId = sourceObjectVersionid
                    };
                    // uploadPartCopy 操作を呼び出して、各パーツをコピーします。
                    var uploadPartCopyResult = client.UploadPartCopy(uploadPartCopyRequest);
                    Console.WriteLine("UploadPartCopy : {0}", i);
                    partETags.Add(uploadPartCopyResult.PartETag);
                }
                // マルチパートコピータスクを完了します。
                var completeMultipartUploadRequest =
                new CompleteMultipartUploadRequest(targetBucket, targetObject, uploadId);
                // partETags は partETag のリストです。OSS は、partETags を受信した後、各パーツを検証します。すべてのパーツが検証されると、OSS はこれらのパーツを完全なオブジェクトに結合します。
                foreach (var partETag in partETags)
                {
                    completeMultipartUploadRequest.PartETags.Add(partETag);
                }
                var completeMultipartUploadResult = client.CompleteMultipartUpload(completeMultipartUploadRequest);
                Console.WriteLine("CompleteMultipartUpload succeeded, vesionid:{0}", completeMultipartUploadResult.VersionId);
            }
            catch (OssException ex)
            {
                Console.WriteLine("Failed with error code: {0}; Error info: {1}. \nRequestID: {2} \tHostID: {3}",
                    ex.ErrorCode, ex.Message, ex.RequestId, ex.HostId);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed with error info: {0}", ex.Message);
            }
        }
    }
}

関連情報

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

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