Object Storage Service (OSS) は、マルチパートアップロード機能を提供します。この機能を使用すると、ラージオブジェクトを複数のパートに分割して、それぞれを個別にアップロードできます。すべてのパートがアップロードされた後、CompleteMultipartUpload 操作を呼び出して、これらのパートを完全なオブジェクトに結合できます。このプロセスにより、再開可能なアップロードが可能になります。
注意事項
このトピックでは、中国 (杭州) リージョンのパブリックエンドポイントを使用します。OSS と同じリージョンにある他の Alibaba Cloud サービスから OSS にアクセスする場合は、内部エンドポイントを使用してください。OSS のリージョンとエンドポイントの詳細については、「リージョンとエンドポイント」をご参照ください。
このトピックでは、OSS エンドポイントを使用して OSSClient インスタンスを作成します。カスタムドメイン名またはセキュリティトークンサービス (STS) を使用して OSSClient を作成する場合は、「OssClient インスタンスの作成」をご参照ください。
InitiateMultipartUpload、UploadPart、CompleteMultipartUpload 操作を含むマルチパートアップロードプロセス全体を完了するには、
oss:PutObject権限が必要です。詳細については、「RAM ユーザーへのカスタム権限の付与」をご参照ください。
操作手順
マルチパートアップロードには、次の 3 つのステップが含まれます。
マルチパートアップロードの開始。
InitiateMultipartUpload 操作を呼び出して、OSS からグローバルに一意なアップロード ID を取得します。
パートのアップロード。
UploadPart 操作を呼び出して、各パートのデータをアップロードします。
説明既存のパートと同じパート番号で新しいパートをアップロードすると、既存のパートは上書きされます。
OSS は、受信したパートデータの MD5 ハッシュを応答の ETag ヘッダーに含めます。
OSS はアップロードされたデータの MD5 ハッシュを計算し、SDK によって計算された MD5 ハッシュと比較します。2 つのハッシュが一致しない場合、OSS は InvalidDigest エラーコードを返します。
マルチパートアップロードの完了。
すべてのパートがアップロードされた後、CompleteMultipartUpload 操作を呼び出して、これらのパートを完全なオブジェクトに結合します。
マルチパートアップロードのサンプルコード
次の例は、完全なマルチパートアップロードプロセスを示しています。
#include <alibabacloud/oss/OssClient.h>
#include <fstream>
int64_t getFileSize(const std::string& file)
{
std::fstream f(file, std::ios::in | std::ios::binary);
f.seekg(0, f.end);
int64_t size = f.tellg();
f.close();
return size;
}
using namespace AlibabaCloud::OSS;
int main(void)
{
/* OSS アカウント情報を初期化します。*/
/* Endpoint を、バケットが所在するリージョンのエンドポイントに設定します。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントを https://oss-cn-hangzhou.aliyuncs.com に設定します。*/
std::string Endpoint = "yourEndpoint";
/* Region を、バケットが所在するリージョンに設定します。たとえば、バケットが中国 (杭州) リージョンにある場合、Region を cn-hangzhou に設定します。*/
std::string Region = "yourRegion";
/* バケット名を指定します。例:examplebucket。*/
std::string BucketName = "examplebucket";
/* オブジェクトの完全なパスを指定します。完全なパスにバケット名を含めることはできません。例:exampledir/exampleobject.txt。*/
std::string ObjectName = "exampledir/exampleobject.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);
InitiateMultipartUploadRequest initUploadRequest(BucketName, ObjectName);
/* (オプション) 次の例に示すように、ストレージクラスを設定します。*/
//initUploadRequest.MetaData().addHeader("x-oss-storage-class", "Standard");
/* マルチパートアップロードイベントを開始します。*/
auto uploadIdResult = client.InitiateMultipartUpload(initUploadRequest);
/* アップロード ID に基づいて、マルチパートアップロードイベントをキャンセルしたり、アップロード済みのパートをリスト表示したりできます。*/
/* アップロード ID に基づいてマルチパートアップロードイベントをキャンセルするには、InitiateMultipartUpload を呼び出してイベントを開始した後にアップロード ID を取得します。*/
/* アップロード ID に基づいてアップロード済みのパートをリスト表示するには、InitiateMultipartUpload を呼び出した後、CompleteMultipartUpload を呼び出す前にアップロード ID を取得します。*/
auto uploadId = uploadIdResult.result().UploadId();
std::string fileToUpload = "yourLocalFilename";
/* パートの最小サイズは 100 KB、最大サイズは 5 GB です。最後のパートのサイズは 100 KB 未満でもかまいません。*/
int64_t partSize = 100 * 1024;
PartList partETagList;
auto fileSize = getFileSize(fileToUpload);
int partCount = static_cast<int>(fileSize / partSize);
/* パート数を計算します。*/
if (fileSize % partSize != 0) {
partCount++;
}
/* 各パートをアップロードします。*/
for (int i = 1; i <= partCount; i++) {
auto skipBytes = partSize * (i - 1);
auto size = (partSize < fileSize - skipBytes) ? partSize : (fileSize - skipBytes);
std::shared_ptr<std::iostream> content = std::make_shared<std::fstream>(fileToUpload, std::ios::in|std::ios::binary);
content->seekg(skipBytes, std::ios::beg);
UploadPartRequest uploadPartRequest(BucketName, ObjectName, content);
uploadPartRequest.setContentLength(size);
uploadPartRequest.setUploadId(uploadId);
uploadPartRequest.setPartNumber(i);
auto uploadPartOutcome = client.UploadPart(uploadPartRequest);
if (uploadPartOutcome.isSuccess()) {
Part part(i, uploadPartOutcome.result().ETag());
partETagList.push_back(part);
}
else {
std::cout << "uploadPart fail" <<
",code:" << uploadPartOutcome.error().Code() <<
",message:" << uploadPartOutcome.error().Message() <<
",requestId:" << uploadPartOutcome.error().RequestId() << std::endl;
}
}
/* マルチパートアップロードを完了します。*/
/* マルチパートアップロードを完了するときは、すべての有効な partETag を提供する必要があります。OSS は partETag を受信した後、各パートを検証します。すべてのパートが検証された後、OSS はそれらを結合して完全なオブジェクトにします。*/
CompleteMultipartUploadRequest request(BucketName, ObjectName);
request.setUploadId(uploadId);
request.setPartList(partETagList);
/* (オプション) 次の例に示すように、アクセス制御リスト (ACL) を設定します。*/
//request.setAcl(CannedAccessControlList::Private);
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;
}CompleteMultipartUpload 操作を呼び出すときは、各パートの ETag 値を提供する必要があります。各パートの ETag 値は、次のいずれかの方法で取得できます。
パートをアップロードすると、応答にそのパートの ETag 値が含まれます。この ETag 値を保存して使用できます。この方法は、上記のサンプルコードで使用されています。
ListParts 操作を呼び出して、アップロードされたすべてのパートの ETag 値をクエリします。
アップロード済みパートのリスト
ListParts 操作を呼び出して、特定のアップロード ID に対して正常にアップロードされたすべてのパートをリスト表示します。
デフォルトでは、一度に最大 1,000 個のアップロード済みパートをリスト表示できます。アップロード済みパートの数が 1,000 を超える場合は、ページ単位でリスト表示する必要があります。
アップロード済みパートのリスト
次のサンプルコードは、アップロード済みパートをリスト表示する方法を示しています。
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;
int main(void)
{
/* OSS アカウント情報を初期化します。*/
/* Endpoint を、バケットが所在するリージョンのエンドポイントに設定します。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントを https://oss-cn-hangzhou.aliyuncs.com に設定します。*/
std::string Endpoint = "yourEndpoint";
/* Region を、バケットが所在するリージョンに設定します。たとえば、バケットが中国 (杭州) リージョンにある場合、Region を cn-hangzhou に設定します。*/
std::string Region = "yourRegion";
/* バケット名を指定します。例:examplebucket。*/
std::string BucketName = "examplebucket";
/* オブジェクトの完全なパスを指定します。完全なパスにバケット名を含めることはできません。例:exampledir/exampleobject.txt。*/
std::string ObjectName = "exampledir/exampleobject.txt";
/* アップロード ID を指定します。アップロード ID は、InitiateMultipartUpload 操作の応答から取得されます。CompleteMultipartUpload 操作を呼び出す前に、アップロード ID を取得する必要があります。*/
std::string UploadId = "yourUploadId";
/* ネットワークリソースを初期化します。*/
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);
/* アップロード済みのパートをリスト表示します。デフォルトでは、最大 1,000 パートがリスト表示されます。*/
ListPartsRequest listuploadrequest(BucketName, ObjectName);
listuploadrequest.setUploadId(UploadId);
bool IsTruncated = false;
do {
auto listUploadResult = client.ListParts(listuploadrequest);
if (!listUploadResult.isSuccess()) {
/* 例外を処理します。*/
std::cout << "ListParts fail" <<
",code:" << listUploadResult.error().Code() <<
",message:" << listUploadResult.error().Message() <<
",requestId:" << listUploadResult.error().RequestId() << std::endl;
break;
}
else {
for (const auto& part : listUploadResult.result().PartList()) {
std::cout << "part"<<
",name:" << part.PartNumber() <<
",size:" << part.Size() <<
",etag:" << part.ETag() <<
",lastmodify time:" << part.LastModified() << std::endl;
}
}
listuploadrequest.setPartNumberMarker(listUploadResult.result().NextPartNumberMarker());
IsTruncated = listUploadResult.result().IsTruncated();
} while (IsTruncated);
/* ネットワークリソースを解放します。*/
ShutdownSdk();
return 0;
}すべてのアップロード済みパートのページ単位でのリスト
次のサンプルコードは、各ページで返すパート数を指定し、すべてのパートをページ単位でリスト表示する方法を示しています。
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;
int main(void)
{
/* OSS アカウント情報を初期化します。*/
/* Endpoint を、バケットが所在するリージョンのエンドポイントに設定します。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントを https://oss-cn-hangzhou.aliyuncs.com に設定します。*/
std::string Endpoint = "yourEndpoint";
/* Region を、バケットが所在するリージョンに設定します。たとえば、バケットが中国 (杭州) リージョンにある場合、Region を cn-hangzhou に設定します。*/
std::string Region = "yourRegion";
/* バケット名を指定します。例:examplebucket。*/
std::string BucketName = "examplebucket";
/* オブジェクトの完全なパスを指定します。完全なパスにバケット名を含めることはできません。例:exampledir/exampleobject.txt。*/
std::string ObjectName = "exampledir/exampleobject.txt";
/* アップロード ID を指定します。アップロード ID は、InitiateMultipartUpload 操作の応答から取得されます。CompleteMultipartUpload 操作を呼び出す前に、アップロード ID を取得する必要があります。*/
std::string UploadId = "yourUploadId";
/* ネットワークリソースを初期化します。*/
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);
/* すべてのアップロード済みパートをページ単位でリスト表示します。*/
/* 各ページで返すパートの最大数を設定します。*/
ListPartsRequest listuploadrequest(BucketName, ObjectName);
listuploadrequest.setMaxParts(50);
listuploadrequest.setUploadId(UploadId);
bool IsTruncated = false;
do {
auto listuploadresult = client.ListParts(listuploadrequest);
if (!listuploadresult.isSuccess()) {
/* 例外を処理します。*/
std::cout << "ListParts fail" <<
",code:" << listuploadresult.error().Code() <<
",message:" << listuploadresult.error().Message() <<
",requestId:" << listuploadresult.error().RequestId() << std::endl;
break;
}
else {
for (const auto& part : listuploadresult.result().PartList()) {
std::cout << "part"<<
",name:" << part.PartNumber() <<
",size:" << part.Size() <<
",etag:" << part.ETag() <<
",lastmodify time:" << part.LastModified() << std::endl;
}
}
listuploadrequest.setPartNumberMarker(listuploadresult.result().NextPartNumberMarker());
IsTruncated = listuploadresult.result().IsTruncated();
} while (IsTruncated);
/* ネットワークリソースを解放します。*/
ShutdownSdk();
return 0;
}マルチパートアップロードイベントのリスト
ListMultipartUploads 操作を呼び出して、進行中のすべてのマルチパートアップロードイベントをリスト表示します。進行中のマルチパートアップロードイベントとは、開始されたが完了もキャンセルもされていないイベントのことです。
デフォルトでは、一度に最大 1,000 件のマルチパートアップロードイベントをリスト表示できます。マルチパートアップロードイベントの数が 1,000 を超える場合は、ページ単位でリスト表示する必要があります。
マルチパートアップロードイベントのリスト
次のサンプルコードは、マルチパートアップロードイベントをリスト表示する方法を示しています。
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;
int main(void)
{
/* OSS アカウント情報を初期化します。*/
/* Endpoint を、バケットが所在するリージョンのエンドポイントに設定します。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントを https://oss-cn-hangzhou.aliyuncs.com に設定します。*/
std::string Endpoint = "yourEndpoint";
/* Region を、バケットが所在するリージョンに設定します。たとえば、バケットが中国 (杭州) リージョンにある場合、Region を cn-hangzhou に設定します。*/
std::string Region = "yourRegion";
/* バケット名を指定します。例:examplebucket。*/
std::string BucketName = "examplebucket";
/* ネットワークリソースを初期化します。*/
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);
/* アップロードイベントをリスト表示します。デフォルトでは、最大 1,000 件のイベントがリスト表示されます。*/
ListMultipartUploadsRequest listmultiuploadrequest(BucketName);
bool IsTruncated = false;
do {
auto listresult = client.ListMultipartUploads(listmultiuploadrequest);
if (!listresult.isSuccess()) {
/* 例外を処理します。*/
std::cout << "ListMultipartUploads fail" <<
",code:" << listresult.error().Code() <<
",message:" << listresult.error().Message() <<
",requestId:" << listresult.error().RequestId() << std::endl;
break;
}
else {
for (const auto& part : listresult.result().MultipartUploadList()) {
std::cout << "part"<<
",name:" << part.Key <<
",uploadid:" << part.UploadId <<
",initiated time:" << part.Initiated << std::endl;
}
}
listmultiuploadrequest.setKeyMarker(listresult.result().NextKeyMarker());
listmultiuploadrequest.setUploadIdMarker(listresult.result().NextUploadIdMarker());
IsTruncated = listresult.result().IsTruncated();
} while (IsTruncated);
/* ネットワークリソースを解放します。*/
ShutdownSdk();
return 0;
}すべてのアップロードイベントのページ単位でのリスト
次のサンプルコードは、すべてのアップロードイベントをページ単位でリスト表示する方法を示しています。
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;
int main(void)
{
/* OSS アカウント情報を初期化します。*/
/* Endpoint を、バケットが所在するリージョンのエンドポイントに設定します。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントを https://oss-cn-hangzhou.aliyuncs.com に設定します。*/
std::string Endpoint = "yourEndpoint";
/* Region を、バケットが所在するリージョンに設定します。たとえば、バケットが中国 (杭州) リージョンにある場合、Region を cn-hangzhou に設定します。*/
std::string Region = "yourRegion";
/* バケット名を指定します。例:examplebucket。*/
std::string BucketName = "examplebucket";
/* ネットワークリソースを初期化します。*/
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);
/* すべてのアップロードイベントをページ単位でリスト表示します。*/
/* 各ページで返すアップロードイベントの最大数を設定します。*/
ListMultipartUploadsRequest listmultiuploadrequest(BucketName);
listmultiuploadrequest.setMaxUploads(50);
bool IsTruncated = false;
do {
auto listresult = client.ListMultipartUploads(listmultiuploadrequest);
if (!listresult.isSuccess()) {
/* 例外を処理します。*/
std::cout << "ListMultipartUploads fail" <<
",code:" << listresult.error().Code() <<
",message:" << listresult.error().Message() <<
",requestId:" << listresult.error().RequestId() << std::endl;
break;
}
else {
for (const auto& part : listresult.result().MultipartUploadList()) {
std::cout << "part"<<
",name:" << part.Key <<
",uploadid:" << part.UploadId <<
",initiated time:" << part.Initiated << std::endl;
}
}
listmultiuploadrequest.setKeyMarker(listresult.result().NextKeyMarker());
listmultiuploadrequest.setUploadIdMarker(listresult.result().NextUploadIdMarker());
IsTruncated = listresult.result().IsTruncated();
} while (IsTruncated);
/* ネットワークリソースを解放します。*/
ShutdownSdk();
return 0;
}マルチパートアップロードイベントのキャンセル
client.AbortMultipartUpload 操作を呼び出して、マルチパートアップロードイベントをキャンセルできます。マルチパートアップロードイベントがキャンセルされると、そのアップロード ID を使用した操作はできなくなります。すでにアップロードされているパートも削除されます。
次のサンプルコードは、マルチパートアップロードイベントをキャンセルする方法を示しています。
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;
int main(void)
{
/* OSS アカウント情報を初期化します。*/
/* Endpoint を、バケットが所在するリージョンのエンドポイントに設定します。たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントを https://oss-cn-hangzhou.aliyuncs.com に設定します。*/
std::string Endpoint = "yourEndpoint";
/* Region を、バケットが所在するリージョンに設定します。たとえば、バケットが中国 (杭州) リージョンにある場合、Region を cn-hangzhou に設定します。*/
std::string Region = "yourRegion";
/* バケット名を指定します。例:examplebucket。*/
std::string BucketName = "examplebucket";
/* オブジェクトの完全なパスを指定します。完全なパスにバケット名を含めることはできません。例:exampledir/exampleobject.txt。*/
std::string ObjectName = "exampledir/exampleobject.txt";
/* アップロード ID を指定します。アップロード ID は、InitiateMultipartUpload 操作の応答から取得されます。*/
std::string UploadId = "yourUploadId";
/* ネットワークリソースを初期化します。*/
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);
InitiateMultipartUploadRequest initUploadRequest(BucketName, ObjectName);
/* マルチパートアップロードイベントを開始します。*/
auto uploadIdResult = client.InitiateMultipartUpload(initUploadRequest);
auto uploadId = uploadIdResult.result().UploadId();
/* マルチパートアップロードイベントをキャンセルします。*/
AbortMultipartUploadRequest abortUploadRequest(BucketName, ObjectName, uploadId);
auto outcome = client.AbortMultipartUpload(abortUploadRequest);
if (!outcome.isSuccess()) {
/* 例外を処理します。*/
std::cout << "AbortMultipartUpload fail" <<
",code:" << outcome.error().Code() <<
",message:" << outcome.error().Message() <<
",requestId:" << outcome.error().RequestId() << std::endl;
return -1;
}
/* ネットワークリソースを解放します。*/
ShutdownSdk();
return 0;
}関連ドキュメント
マルチパートアップロードの完全なサンプルコードについては、GitHub の例をご参照ください。
マルチパートアップロードには 3 つの API 操作が含まれます。操作の詳細については、次のトピックをご参照ください。
マルチパートアップロードイベントを中止するために使用される API 操作の詳細については、「AbortMultipartUpload」をご参照ください。
アップロード済みのパートをリスト表示するために使用される API 操作の詳細については、「ListUploadedParts」をご参照ください。
開始されたがまだ完了または中止されていない、進行中のすべてのマルチパートアップロードイベントをリスト表示するために使用される API 操作の詳細については、「ListMultipartUploads」をご参照ください。