このトピックでは、同一リージョン内のバケット内、またはバケット間でオブジェクトをコピーする方法について説明します。
注意事項
このトピックでは、中国 (杭州) リージョンのパブリックエンドポイントを使用します。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 を使用してパートを順次コピーする必要があります。マルチパートコピーを実装するには、次の手順を実行します。
client.InitiateMultipartUpload を使用して、マルチパートコピータスクを開始します。
client.UploadPartCopy を使用してパートをコピーします。最後のパートを除き、すべてのパートは 100 KB より大きい必要があります。
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」をご参照ください。