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

Object Storage Service:オブジェクトのコピー (C# SDK V1)

最終更新日:Nov 30, 2025

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

注意事項

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

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

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

小規模オブジェクトのコピー

1 GB 未満のファイルの場合は、CopyObject メソッドを使用して、同じリージョン内のソースバケットから宛先バケットにファイルをコピーします。

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

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

  • 宛先バケットでバージョン管理が有効になっている場合、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 操作は、既存のオブジェクトの現在のバージョンからパートをコピーします。オブジェクトの特定のバージョンからパートをコピーするには、`x-oss-copy-source` リクエストヘッダーに versionId サブリソースを追加します。例:`x-oss-copy-source: /SourceBucketName/SourceObjectName?versionId=CAEQMxiBgICAof2D0BYiIDJhMGE3N2M1YTI1NDQzOGY5NTkyNTI3MGYyMzJm****`。

説明

`SourceObjectName` は URL エンコードする必要があります。レスポンスは、`x-oss-copy-source-version-id` でソースオブジェクトのバージョン ID を返します。

versionId を指定せず、ソースオブジェクトの現在のバージョンが削除マーカーである場合、OSS は 404 Not Found を返します。削除マーカーの versionId を指定した場合、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」をご参照ください。