このトピックでは、同一リージョン内のバケット内、またはバケット間でオブジェクトをコピーする方法について説明します。
注意事項
このトピックでは、中国 (杭州) リージョンのパブリックエンドポイントを使用します。Object Storage Service (OSS) と同じリージョンにある他の Alibaba Cloud サービスから OSS にアクセスする場合は、内部エンドポイントを使用してください。OSS のリージョンとエンドポイントの詳細については、「リージョンとエンドポイント」をご参照ください。
このトピックでは、OSS エンドポイントを使用して OSSClient インスタンスを作成します。カスタムドメイン名または Security Token Service (STS) を使用して OSSClient インスタンスを作成する場合は、「初期化」をご参照ください。
オブジェクトをコピーするには、ソースオブジェクトに対する読み取り権限と、宛先バケットに対する読み取りおよび書き込み権限が必要です。
ソースバケットと宛先バケットに保持ポリシーが設定されていないことを確認してください。設定されている場合、エラーメッセージ The object you specified is immutable. が返されます。
ソースバケットと宛先バケットは、同じリージョンにある必要があります。たとえば、中国 (杭州) リージョンにあるバケットから中国 (青島) リージョンにある別のバケットにオブジェクトをコピーすることはできません。
スモールオブジェクトのコピー
次のコードは、スモールオブジェクトをコピーする方法の例を示しています。
using Aliyun.OSS;
using Aliyun.OSS.Common;
// バケットが配置されているリージョンのエンドポイントを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントを 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");
// ソースバケットの名前を指定します。例:srcexamplebucket。
var sourceBucket = "srcexamplebucket";
// ソースオブジェクトの完全なパスを指定します。完全なパスにバケット名を含めることはできません。例:srcdir/scrobject.txt。
var sourceObject = "srcdir/scrobject.txt";
// 宛先バケットの名前を指定します。ソースバケットと同じリージョンにある必要があります。例:destbucket。
var targetBucket = "destbucket";
// 宛先オブジェクトの完全なパスを指定します。完全なパスにバケット名を含めることはできません。例:destdir/destobject.txt。
var targetObject = "destdir/destobject.txt";
// バケットが配置されているリージョンを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合、リージョンを cn-hangzhou に設定します。
const string region = "cn-hangzhou";
// ClientConfiguration インスタンスを作成し、必要に応じてデフォルトのパラメーターを変更します。
var conf = new ClientConfiguration();
// Signature V4 を使用します。
conf.SignatureVersion = SignatureVersion.V4;
// OssClient インスタンスを作成します。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret, conf);
client.SetRegion(region);
try
{
var metadata = new ObjectMetadata();
// カスタムメタデータを設定します。カスタムメタデータはキーと値のペアです。たとえば、キーを mk1、値を mv1 に設定します。
metadata.AddHeader("mk1", "mv1");
metadata.AddHeader("mk2", "mv2");
var req = new CopyObjectRequest(sourceBucket, sourceObject, targetBucket, targetObject)
{
// NewObjectMetadata が null の場合、ソースオブジェクトのメタデータがコピーされます (COPY モード)。NewObjectMetadata が null でない場合、ソースオブジェクトのメタデータが上書きされます (REPLACE モード)。
NewObjectMetadata = metadata
};
// オブジェクトをコピーします。
client.CopyObject(req);
Console.WriteLine("Copy object succeeded");
}
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 を使用してパートを順次コピーする必要があります。マルチパートコピーを実装するには、次の手順を実行します。
InitiateMultipartUploadRequest メソッドを使用して、マルチパートアップロードイベントを初期化します。
UploadPartCopy メソッドを使用して、パートをコピーします。
CompleteMultipartUpload メソッドを使用して、オブジェクトのコピーを完了します。
次のコードは、マルチパートコピーを実行する方法を示しています。
using Aliyun.OSS; using Aliyun.OSS.Common; // バケットが配置されているリージョンのエンドポイントを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントを 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"); // ソースバケットの名前を指定します。例:srcexamplebucket。 var sourceBucket = "srcexamplebucket"; // ソースオブジェクトの完全なパスを指定します。完全なパスにバケット名を含めることはできません。例:srcdir/scrobject.txt。 var sourceObject = "srcdir/scrobject.txt"; // 宛先バケットの名前を指定します。ソースバケットと同じリージョンにある必要があります。例:destbucket。 var targetBucket = "destbucket"; // 宛先オブジェクトの完全なパスを指定します。完全なパスにバケット名を含めることはできません。例:destdir/destobject.txt。 var targetObject = "destdir/destobject.txt"; var uploadId = ""; var partSize = 50 * 1024 * 1024; // バケットが配置されているリージョンを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合、リージョンを cn-hangzhou に設定します。 const string region = "cn-hangzhou"; // ClientConfiguration インスタンスを作成し、必要に応じてデフォルトのパラメーターを変更します。 var conf = new ClientConfiguration(); // Signature V4 を使用します。 conf.SignatureVersion = SignatureVersion.V4; // OssClient インスタンスを作成します。 var client = new OssClient(endpoint, accessKeyId, accessKeySecret, conf); client.SetRegion(region); try { // コピータスクを初期化します。InitiateMultipartUploadRequest を使用して、宛先オブジェクトのメタデータを指定できます。 var request = new InitiateMultipartUploadRequest(targetBucket, targetObject); var result = client.InitiateMultipartUpload(request); // アップロード ID を出力します。 uploadId = result.UploadId; Console.WriteLine("Init multipart upload succeeded, Upload Id: {0}", result.UploadId); // パート数を計算します。 var metadata = client.GetObjectMetadata(sourceBucket, sourceObject); 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 }; // 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 はこのリストを受け取ると、各パートを検証します。すべてのパートが有効な場合、OSS はそれらを結合して完全なオブジェクトを作成します。 foreach (var partETag in partETags) { completeMultipartUploadRequest.PartETags.Add(partETag); } var completeMultipartUploadResult = client.CompleteMultipartUpload(completeMultipartUploadRequest); Console.WriteLine("CompleteMultipartUpload succeeded"); } 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); }再開可能コピー
コピータスクが中断された場合、ブレークポイントから再開できます。
次のコードは、再開可能コピーを実行する方法を示しています。
using Aliyun.OSS; // バケットが配置されているリージョンのエンドポイントを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントを 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"); // ソースバケットの名前を指定します。例:srcexamplebucket。 var sourceBucket = "srcexamplebucket"; // ソースオブジェクトの完全なパスを指定します。完全なパスにバケット名を含めることはできません。例:srcdir/scrobject.txt。 var sourceObject = "srcdir/scrobject.txt"; // 宛先バケットの名前を指定します。ソースバケットと同じリージョンにある必要があります。例:destbucket。 var targetBucket = "destbucket"; // 宛先オブジェクトの完全なパスを指定します。完全なパスにバケット名を含めることはできません。例:destdir/destobject.txt。 var targetObject = "destdir/destobject.txt"; // コピー結果を記録するファイルを指定します。進行状況情報はこのファイルに保存されます。コピータスクが失敗した場合、記録されたブレークポイントから再開されます。コピーが完了すると、このファイルは削除されます。 var checkpointDir = @"yourCheckpointDir"; // バケットが配置されているリージョンを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合、リージョンを cn-hangzhou に設定します。 const string region = "cn-hangzhou"; // ClientConfiguration インスタンスを作成し、必要に応じてデフォルトのパラメーターを変更します。 var conf = new ClientConfiguration(); // Signature V4 を使用します。 conf.SignatureVersion = SignatureVersion.V4; // OssClient インスタンスを作成します。 var client = new OssClient(endpoint, accessKeyId, accessKeySecret, conf); client.SetRegion(region); try { var request = new CopyObjectRequest(sourceBucket, sourceObject, targetBucket, targetObject); // checkpointDir ディレクトリは、再開可能コピーのための中間状態を保存します。これにより、障害発生後にタスクを再開できます。checkpointDir が null の場合、再開可能コピー機能は無効になり、コピータスクは毎回最初から開始されます。 client.ResumableCopyObject(request, checkpointDir); Console.WriteLine("Resumable copy new object:{0} succeeded", request.DestinationKey); } catch (Exception ex) { Console.WriteLine("Resumable copy new object failed, {0}", ex.Message); }
関連ドキュメント
スモールオブジェクトのコピー
スモールオブジェクトのコピーに使用される完全なサンプルコードについては、GitHub をご参照ください。
スモールオブジェクトのコピーに使用される API 操作の詳細については、「CopyObject」をご参照ください。
ラージオブジェクトのコピー
ラージオブジェクトのコピーに使用される完全なサンプルコードについては、GitHub をご参照ください。
ラージオブジェクトのコピーに使用される API 操作の詳細については、「UploadPartCopy」をご参照ください。
再開可能コピー
再開可能コピーに使用される完全なサンプルコードについては、GitHub をご参照ください。