Object Storage Service (OSS) は、マルチパートアップロード機能を提供します。 この機能を使用すると、大きなオブジェクトを複数のパーツに分割し、パーツを個別にアップロードできます。 アップロードが完了したら、CompleteMultipartUpload操作を呼び出して、これらのパーツを完全なオブジェクトに結合できます。
使用上の注意
このトピックのサンプルコードを実行する前に、カスタムドメイン名やSecurity Token Service (STS) などの方法を使用してOSSClientインスタンスを作成する必要があります。 詳細については、「初期化」をご参照ください。
説明OSSClientインスタンスを初期化するときに、バケットのリージョンにマップされるエンドポイントを指定します。
オブジェクトをアップロードするには、
oss:PutObject
権限が必要です。 詳細については、「RAMユーザーへのカスタムポリシーのアタッチ」をご参照ください。
マルチパートアップロードプロセス
マルチパートアップロードを実行するには、次の手順を実行します。
アップロードするオブジェクトをパーツに分割します。
InitiateMultipartUpload操作を呼び出して、マルチパートアップロードタスクを開始します。
UploadPart操作を呼び出して、パーツを1つずつ、または並行してアップロードします。
CompleteMultipartUpload操作を呼び出して、アップロードタスクを完了します。
マルチパートアップロードタスクを開始する前に、次の項目に注意してください。
最後の部分を除く各部分のサイズは少なくとも100 KBでなければなりません。 それ以外の場合、CompleteMultipartUpload操作は失敗します。
オブジェクト内の部品の位置は、アップロード処理中に指定した部品番号によって決まります。 パーツは順番にアップロードする必要はなく、同時にアップロードできます。
パーツを同時にアップロードするには、ネットワークの状態とデバイスの負荷に基づいて適切な同時実行レベルを指定する必要があります。 より高い同時実行レベルは、必ずしもより速いアップロード速度を意味しない。 ネットワーク状態が安定している場合は部品サイズを大きくし、ネットワーク状態が不安定な場合は部品サイズを小さくすることを推奨します。
既定では、オブジェクトのパーツをアップロードしてCompleteMultipartUpload操作を呼び出してこれらのパーツを結合しない場合、アップロードされたパーツは自動的に削除されません。 AbortMultipartUpload操作を呼び出して、アップロードタスクを終了し、パーツを削除できます。 アップロードされたパーツを自動的に削除する方法の詳細については、「最終変更時刻に基づくライフサイクルルール」をご参照ください。
マルチパートアップロードタスクの完全なサンプルコード
次のサンプルコードは、マルチパートアップロードタスクを実装する方法の完全な例を示しています。
__block NSString * uploadId = nil;
__ブロックNSMutableArray * partInfos = [NSMutableArray new];
// バケットの名前を指定します。 例: examplebucket.
NSString * uploadToBucket = @ "examplebucket";
// オブジェクトのフルパスを指定します。 例: exampledir/exampleobject.txt。 バケット名をフルパスに含めないでください。
NSString * uploadObjectkey = @ "exampledir/exampleobject.txt";
// OSSInitMultipartUploadRequestを使用して、アップロードされたオブジェクトの名前と、オブジェクトが格納されているバケットの名前を指定します。
OSSInitMultipartUploadRequest * init = [OSSInitMultipartUploadRequest new];
init.bucketName = uploadToBucket;
init.objectKey = uploadObjectkey;
// init.contentType = @ "application/octet-stream";
// multipartUploadInitへの応答には、アップロードIDが含まれます。 アップロードIDは、マルチパートアップロードタスクの一意のIDです。
OSSTask * initTask = [client multipartUploadInit:init];
[initTask waitUntilFinished];
if (!initTask.error) {
OSSInitMultipartUploadResult * result = initTask.result;
uploadId = result.uploadId;
// マルチパートアップロードタスクをキャンセルするか、アップロードIDに基づいてアップロードされたパーツをリストします。
// アップロードIDに基づいてマルチパートアップロードタスクをキャンセルする場合は、InitiateMultipartUpload操作を呼び出してマルチパートアップロードタスクを開始した後にアップロードIDを取得します。
// アップロードIDに基づいてマルチパートアップロードタスクでアップロードされたパーツを一覧表示する場合は、InitiateMultipartUpload操作を呼び出してマルチパートアップロードタスクを開始した後、CompleteMultipartUpload操作を呼び出してマルチパートアップロードタスクを完了する前に、アップロードIDを取得します。
// NSLog(@ "UploadId": %@, uploadId);
} else {
NSLog(@ "マルチパートアップロードに失敗しました、エラー: % @" 、initTask.error);
戻ります。}
// アップロードするオブジェクトを指定します。
NSString * filePath = @ "<filepath>";
// オブジェクトのサイズを照会します。
uint64_t fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil] fileSize];
// 部品の数を指定します。
int chuckCount = 10;
// パーツサイズを指定します。
uint64_tオフセット=fileSize/chuckCount;
for (int i = 1; i <= chuckCount; i ++) {
OSSUploadPartRequest * uploadPart = [OSSUploadPartRequest new];
uploadPart.bucketName = uploadToBucket;
uploadPart.objectkey = uploadObjectkey;
uploadPart.uploadId = uploadId;
uploadPart.partNumber = i; // 部品番号は1から始まります
NSFileHandle * readHandle = [NSFileHandleForReadingAtPath: filePath];
[readHandle seekToFileOffset:offset * (i -1)];
NSData * data = [readHandle readDataOfLength: オフセット];
uploadPart.uploadPartData=データ;
OSSTask * uploadPartTask = [クライアントuploadPart:uploadPart];
[uploadPartTask waitUntilFinished];
if (!uploadPartTask.error) {
OSSUploadPartResult * result = uploadPartTask.result;
uint64_t fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:uploadPart.uploadPartFileURL.absoluteStringエラー: nil] fileSize];
[partInfos addObject:[OSSPartInfo partInfoWithPartNum:i eTag:result.eTagサイズ: fileSize]];
} else {
NSLog(@ "upload part error: % @", uploadPartTask.error);
戻る;
}
}
OSSCompleteMultipartUploadRequest * complete = [OSSCompleteMultipartUploadRequest new];
complete.bucketName = uploadToBucket;
complete.objectKey = uploadObjectkey;
complete.uploadId = uploadId;
complete.partInfos = partInfos;
OSSTask * completeTask = [client completeMultipartUpload:complete];
[[completeTask continueWithBlock:^ id(OSSTask * task) {
if (!task.error) {
OSSCompleteMultipartUploadResult * result = task.result;
// ...
} else {
// ...
}
nilを返します。}] waitUntilFinished];
マルチパートアップロードを使用してローカルファイルをアップロードする
上記の完全なサンプルコードは、マルチパートアップロードプロセスに従ってマルチパートアップロードタスクを実装しています。 次のサンプルコードは、前述の完全なサンプルコードをカプセル化して、MultipartUploadRequestを使用してローカルファイルを部分的にアップロードできるようにします。
次のサンプルコードは、マルチパートアップロードを使用してローカルファイルをアップロードする方法の例を示しています。
// バケットの名前を指定します。 例: examplebucket.
NSString * bucketName = @ "examplebucket";
// オブジェクトのフルパスを指定します。 例: exampledir/exampleobject.txt。 バケット名をフルパスに含めないでください。
NSString * objectKey = @ "exampledir/exampleobject.txt";
OSSMultipartUploadRequest * multipartUploadRequest = [OSSMultipartUploadRequest new];
multipartUploadRequest.bucketName = bucketName;
multipartUploadRequest.objectKey = objectKey;
// パーツサイズを指定します。 デフォルトの部品サイズは256 KBです。
multipartUploadRequest.partSize = 1024*1024;
multipartUploadRequest.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {
NSLog(@ "progress: % lld, % lld, % lld", bytesSent, totalByteSent, totalBytesExpectedToSend);
};
multipartUploadRequest.uploadingFileURL = [[NSBundle mainBundle] URLForResource:@ "wangwang" withExtension:@ "zip"];
OSSTask * multipartTask = [client multipartUpload:multipartUploadRequest];
[[multipartTask continueWithBlock:^ id(OSSTask * task)) {
if (task.error) {
NSLog(@ "error: % @" 、task.error);
} else {
NSLog(@ "ファイルのアップロード成功");
}
nilを返します。}] waitUntilFinished];
アップロードしたパーツの一覧表示
次のサンプルコードでは、listParts
を使用してマルチパートアップロードタスクのアップロードされたすべてのパートを一覧表示する方法の例を示します。
OSSListPartsRequest * listParts = [OSSListPartsRequest new];
// バケットの名前を指定します。 例: examplebucket.
listParts.bucketName = @ "examplebucket";
// オブジェクトのフルパスを指定します。 例: exampledir/exampleobject.txt。 バケット名をフルパスに含めないでください。
listParts.objectKey = @ "exampledir/exampleobject.txt";
// アップロードIDを指定します。 InitiateMultipartUpload操作の応答からアップロードIDを取得できます。 CompleteMultipartUpload操作を呼び出してマルチパートアップロードタスクを完了する前に、アップロードIDを取得する必要があります。
listParts.uploadId = @ "0004B999EF518A1FE585B0C9 ****";
OSSTask * listPartTask = [client listParts:listParts];
[listPartTask continueWithBlock:^ id(OSSTask * task) {
if (!task.error) {
NSLog(@ "リストパート結果の成功!");
OSSListPartsResult * listPartResult = task.result;
for (listPartResult.partsのNSDictionary * partInfo) {
NSLog(@ "各パート: % @", partInfo);
}
} else {
NSLog(@ "list part result error: % @" 、task.error);
}
nilを返します。}];
// waitUntilFinishedは現在のスレッドの実行をブロックしますが、タスクの進行はブロックしません。
// [listPartTask waitUntilFinished];
デフォルトでは、マルチパートアップロードを使用してアップロードされた1,000を超えるパーツがバケットに含まれている場合、最初の1,000パーツが返されます。 応答では、IsTruncatedフィールドの値はfalseであり、次のリスト操作の開始位置を示すためにNextPartNumberMarkerが返されます。
マルチパートアップロードタスクのキャンセル
次のサンプルコードは、特定のアップロードID
を持つマルチパートアップロードタスクをキャンセルする方法の例を示しています。
OSSAbortMultipartUploadRequest * abort = [OSSAbortMultipartUploadRequest new];
// バケットの名前を指定します。 例: examplebucket.
abort.bucketName = @ "examplebucket";
// オブジェクトのフルパスを指定します。 例: exampledir/exampleobject.txt。 バケット名をフルパスに含めないでください。
abort.objectKey = @ "exampledir/exampleobject.txt";
// アップロードIDを指定します。 InitiateMultipartUpload操作の応答からアップロードIDを取得できます。
abort.uploadId = @ "0004B999EF518A1FE585B0C9 ****";
OSSTask * abortTask = [client abortMultipartUpload:abort];
[abortTask waitUntilFinished];
if (!abortTask.error) {
OSSAbortMultipartUploadResult * result = abortTask.result;
uploadId = result.uploadId;
} else {
NSLog(@ "マルチパートアップロードに失敗しました、エラー: % @" 、abortTask.error);
戻ります。}
// waitUntilFinishedは現在のスレッドの実行をブロックしますが、タスクの進行はブロックしません。
// [abortTask waitUntilFinished];
関連ドキュメント
マルチパートアップロードの実行に使用する完全なサンプルコードについては、『GitHub』をご参照ください。
マルチパートアップロードには3つのAPI操作が含まれます。 操作の詳細については、以下のトピックを参照してください。
アップロードされたパーツを一覧表示するために呼び出すことができるAPI操作の詳細については、「ListParts」をご参照ください。
マルチパートアップロードタスクをキャンセルするために呼び出すことができるAPI操作の詳細については、「AbortMultipartUpload」をご参照ください。