Object Storage Service (OSS) は、ラージオブジェクトを複数のパートに分割できるマルチパートアップロード機能を提供します。これらのパートがアップロードされた後、CompleteMultipartUpload 操作を呼び出して、それらを完全なオブジェクトに結合できます。
使用上の注意
OSS がサポートするリージョンとエンドポイントの詳細については、「リージョンとエンドポイント」をご参照ください。
マルチパートアップロードを実行するには、
oss:PutObject権限が必要です。詳細については、「カスタムポリシーを使用した RAM ユーザーへの権限付与」をご参照ください。
マルチパートアップロードのプロセス
マルチパートアップロードは、以下の 3 つのステップで構成されます:
マルチパートアップロードの開始。
client.initiateMultipartUpload メソッドを呼び出します。OSS はグローバルに一意なアップロード ID を返します。
パーツをアップロードします。
client.uploadPart メソッドを呼び出してパートをアップロードします。
説明特定のアップロード ID に対して、パート番号は完全なオブジェクト内でのパートの相対的な位置を識別します。既存のパート番号で新しいパートをアップロードすると、既存のパートは上書きされます。
OSS は、受信したパートの MD5 ハッシュを ETag ヘッダーで返します。
OSS はアップロードされたデータの MD5 ハッシュを計算し、SDK によって計算された MD5 ハッシュと比較します。2 つのハッシュが一致しない場合、OSS は `InvalidDigest` エラーコードを返します。
マルチパートアップロードの完了。
すべてのパートがアップロードされた後、client.completeMultipartUpload メソッドを呼び出して、パートを完全なオブジェクトに結合できます。
サンプルコード
以下のコードは、大きなローカルファイルを複数のパートに分割し、それらのパートをバケットに同時にアップロードしてから、パートを完全なオブジェクトに結合する方法を示しています。
import Client, { FilePath, RequestError, THarmonyEmptyBodyApiRes } from '@aliyun/oss';
import { fileIo as fs } from '@kit.CoreFileKit';
// OSS クライアントインスタンスを作成します。
const client = new Client({
// STS 一時アクセス認証情報から取得した AccessKey ID に置き換えてください。
accessKeyId: 'yourAccessKeyId',
// STS 一時アクセス認証情報から取得した AccessKey Secret に置き換えてください。
accessKeySecret: 'yourAccessKeySecret',
// STS 一時アクセス認証情報から取得したセキュリティトークンに置き換えてください。
securityToken: 'yourSecurityToken',
// バケットが配置されているリージョンを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合は、リージョンを oss-cn-hangzhou に設定します。
region: 'oss-cn-hangzhou',
});
// 使用するバケットの名前を指定します。実際のバケット名に置き換えてください。
const bucket = 'yourBucketName';
// アップロードするオブジェクト (ファイル) の名前を指定します。実際のオブジェクト名に置き換えてください。
const key = 'yourObjectName';
/**
* マルチパートアップロードを使用してファイルを OSS にアップロードします。
* マルチパートアップロードを使用して、大きなファイルを複数のパートに分割し、指定されたバケットとキーにアップロードします。
*/
const multipartUpload = async () => {
try {
// マルチパートアップロードタスクを開始し、uploadId を取得します。
const initRes = await client.initiateMultipartUpload({
bucket, // バケット名
key, // オブジェクト (ファイル) 名
});
// 初期化応答から uploadId を取得します。これは、後続のパートのアップロードとアップロードの完了に使用されます。
const uploadId = initRes.data.uploadId;
// ローカルファイルパスを指定します。
const filePath = new FilePath('yourFilePath');// 実際のローカルファイルパスに置き換えてください。
// ファイルサイズなどのファイルメタデータを取得します。
const fileStat = await fs.stat(filePath.filePath);
// 各パートのサイズを定義します (10 MB)。
const chunkSize = 1024 * 1024 * 10;
// パートの総数を計算します。
let totalParts = Math.ceil(fileStat.size / chunkSize);
// 現在のパート番号。
let partNumber = 1;
// すべてのパートアップロードの Promise オブジェクトを格納します。
const waitList: Promise<THarmonyEmptyBodyApiRes>[] = [];
// 各パートを処理するためのループ。
while (partNumber <= totalParts) {
// 現在のパートの開始位置を計算します。
const offset = (partNumber - 1) * chunkSize;
// uploadPart メソッドを呼び出して現在のパートをアップロードします。
const uploadPromise = client.uploadPart({
bucket, // バケット名
key, // オブジェクト (ファイル) 名
uploadId, // 初期化から返された uploadId。
partNumber, // 現在のパート番号。
data: filePath, // ファイルパス。
length: Math.min(chunkSize, fileStat.size - offset), // 現在のパートのサイズ。
offset, // 現在のパートの開始オフセット。
});
// パートアップロードの Promise を待機リストに追加します。
waitList.push(uploadPromise);
// パート番号をインクリメントします。
partNumber++;
}
// すべてのパートのアップロードが完了するのを待ちます。
const uploadResList = await Promise.all(waitList);
// すべてのパートがアップロードされた後、completeMultipartUpload を呼び出してアップロードタスクを完了します。
const completeRes = await client.completeMultipartUpload({
bucket, // バケット名
key, // オブジェクト (ファイル) 名
uploadId, // 初期化から返された uploadId。
completeAll: true, // すべてのパートを自動的に完了させます。
});
// 完了したマルチパートアップロードの結果を出力します。
console.log(JSON.stringify(completeRes));
} catch (err) {
// リクエスト中に発生した例外をキャッチします。
if (err instanceof RequestError) {
// 既知のタイプのエラーが発生した場合は、エラーコード、エラーメッセージ、リクエスト ID、ステータスコード、EC コードなどの情報を出力します。
console.log('code: ', err.code); // エラーコード。
console.log('message: ', err.message); // エラーメッセージ。
console.log('requestId: ', err.requestId); // リクエスト ID。
console.log('status: ', err.status); // HTTP ステータスコード。
console.log('ec: ', err.ec); // エラーコード。
} else {
// その他の不明なタイプのエラーを出力します。
console.log('unknown error: ', err);
}
}
};
// multipartUpload 関数を呼び出して、マルチパートアップロード操作を実行します。
multipartUpload();