Object Storage Service (OSS) は、マルチパートアップロード機能を提供します。この機能を使用すると、大きなオブジェクトを複数のパートに分割し、それぞれを個別にアップロードできます。すべてのパートがアップロードされた後、`CompleteMultipartUpload` 操作を呼び出して、パートを完全なオブジェクトに結合できます。このプロセスにより、再開可能なアップロードが可能になります。
注意事項
このトピックでは、中国 (杭州) リージョンのパブリックエンドポイントを使用します。同じリージョン内の他の Alibaba Cloud サービスから OSS にアクセスするには、内部エンドポイントを使用します。サポートされているリージョンとエンドポイントの詳細については、「リージョンとエンドポイント」をご参照ください。
このトピックでは、アクセス認証情報は環境変数から取得されます。アクセス認証情報の設定方法の詳細については、「アクセス認証情報の設定」をご参照ください。
このトピックでは、OSS エンドポイントを使用して `OSSClient` インスタンスを作成します。カスタムドメイン名または Security Token Service (STS) を使用して `OSSClient` インスタンスを作成する場合は、「一般的なシナリオの設定例」をご参照ください。
`InitiateMultipartUpload`、`UploadPart`、`CompleteMultipartUpload` 操作を含むマルチパートアップロードプロセスを完了するには、
oss:PutObject権限が必要です。詳細については、「RAM ユーザーへのカスタムアクセスポリシーの付与」をご参照ください。
マルチパートアップロードのプロセス
マルチパートアップロードは、次の 3 つのステップで構成されます。
マルチパートアップロードイベントの初期化
`ossClient.initiateMultipartUpload` メソッドを呼び出します。OSS は、レスポンスでグローバルに一意のアップロード ID を返します。
パートのアップロード
`ossClient.uploadPart` メソッドを呼び出して、パートデータをアップロードします。
説明同じアップロード ID の場合、パート番号はファイル全体におけるパートの位置を識別します。同じパート番号で新しいデータをアップロードすると、OSS 内の既存のパートデータは上書きされます。
OSS は、レスポンスの ETag ヘッダーで、受信したパートデータの MD5 ハッシュを返します。
OSS は、アップロードされたデータの MD5 ハッシュを計算し、SDK によって計算された MD5 ハッシュと比較します。2 つの MD5 ハッシュが一致しない場合、`InvalidDigest` エラーコードが返されます。
マルチパートアップロードの完了
すべてのパートがアップロードされた後、`ossClient.completeMultipartUpload` メソッドを呼び出して、パートを完全なファイルにマージします。
コード例
次の例は、完全なマルチパートアップロードのプロセスを示しています。
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.internal.Mimetypes;
import com.aliyun.oss.model.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
public class Demo {
public static void main(String[] args) throws Exception {
// 例として、中国 (杭州) リージョンのエンドポイントを使用します。実際のエンドポイントを指定してください。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 環境変数からアクセス認証情報を取得します。サンプルコードを実行する前に、OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET 環境変数が設定されていることを確認してください。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// バケット名を指定します (例: examplebucket)。
String bucketName = "examplebucket";
// オブジェクトのフルパスを指定します (例: exampledir/exampleobject.txt)。フルパスにバケット名を含めることはできません。
String objectName = "exampledir/exampleobject.txt";
// アップロードするローカルファイルのパス。
String filePath = "D:\\localpath\\examplefile.txt";
// バケットが配置されているリージョンを指定します。たとえば、バケットが中国 (杭州) リージョンにある場合は、リージョンを cn-hangzhou に設定します。
String region = "cn-hangzhou";
// OSSClient インスタンスを作成します。
// OSSClient インスタンスが不要になったら、shutdown メソッドを呼び出してリソースを解放します。
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
OSS ossClient = OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region(region)
.build();
try {
// InitiateMultipartUploadRequest オブジェクトを作成します。
InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, objectName);
// ObjectMetadata オブジェクトを作成し、Content-Type を設定します。
ObjectMetadata metadata = new ObjectMetadata();
if (metadata.getContentType() == null) {
metadata.setContentType(Mimetypes.getInstance().getMimetype(new File(filePath), objectName));
}
System.out.println("Content-Type: " + metadata.getContentType());
// メタデータをアップロードリクエストにバインドします。
request.setObjectMetadata(metadata);
// マルチパートアップロードを初期化します。
InitiateMultipartUploadResult upresult = ossClient.initiateMultipartUpload(request);
// アップロード ID を返します。
String uploadId = upresult.getUploadId();
// partETags は PartETag オブジェクトのコレクションです。PartETag オブジェクトは、パートの ETag とパート番号で構成されます。
List<PartETag> partETags = new ArrayList<PartETag>();
// 各パートのサイズ。これはパート数を計算するために使用されます。単位:バイト。
// 最小パートサイズは 100 KB、最大パートサイズは 5 GB です。最後のパートのサイズは 100 KB より小さくてもかまいません。
// パートサイズを 1 MB に設定します。
final long partSize = 1 * 1024 * 1024L;
// アップロードするデータのサイズに基づいてパート数を計算します。次のコードは、File.length() を使用してローカルファイルからアップロードするデータのサイズを取得する方法の例です。
final File sampleFile = new File(filePath);
long fileLength = sampleFile.length();
int partCount = (int) (fileLength / partSize);
if (fileLength % partSize != 0) {
partCount++;
}
// パートを走査してアップロードします。
for (int i = 0; i < partCount; i++) {
long startPos = i * partSize;
long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize;
UploadPartRequest uploadPartRequest = new UploadPartRequest();
uploadPartRequest.setBucketName(bucketName);
uploadPartRequest.setKey(objectName);
uploadPartRequest.setUploadId(uploadId);
// アップロードするパートのストリームを設定します。
// 次のコードは、ローカルファイルから FileInputStream オブジェクトを作成し、InputStream.skip() メソッドを使用して指定されたデータをスキップする方法の例です。
InputStream instream = new FileInputStream(sampleFile);
instream.skip(startPos);
uploadPartRequest.setInputStream(instream);
// パートサイズを設定します。
uploadPartRequest.setPartSize(curPartSize);
// パート番号を設定します。アップロードされた各パートには、1 から 10,000 の範囲のパート番号があります。パート番号がこの範囲にない場合、OSS は InvalidArgument エラーコードを返します。
uploadPartRequest.setPartNumber(i + 1);
// パートは順番にアップロードする必要はありません。異なるクライアントからアップロードすることも可能です。OSS はパート番号でパートをソートして、完全なファイルを作成します。
UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
// 各パートがアップロードされると、OSS レスポンスには PartETag が含まれます。PartETag は partETags に保存されます。
partETags.add(uploadPartResult.getPartETag());
// ストリームを閉じます。
instream.close();
}
// CompleteMultipartUploadRequest オブジェクトを作成します。
// マルチパートアップロードを完了するときは、すべての有効な partETags を提供する必要があります。OSS は、送信された partETags を受信した後、各パートの有効性を検証します。すべてのパートが検証された後、OSS はこれらのパートを完全なファイルに結合します。
CompleteMultipartUploadRequest completeMultipartUploadRequest =
new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags);
// マルチパートアップロードを完了します。
CompleteMultipartUploadResult completeMultipartUploadResult = ossClient.completeMultipartUpload(completeMultipartUploadRequest);
System.out.println("Upload successful, ETag: " + completeMultipartUploadResult.getETag());
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught a ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}一般的なシナリオ
マルチパートアップロードの初期化時のメタデータ設定
マルチパートアップロード完了時のファイルアクセス権限の設定
マルチパートアップロード完了時の part ETag の自動処理
マルチパートアップロードイベントのキャンセル
アップロード済みパートのリスト表示
マルチパートアップロードイベントのリスト表示
ネットワークストリームまたはデータストリームのマルチパートアップロードの実行
関連ドキュメント
マルチパートアップロードの完全なサンプルコードについては、「GitHub の例」をご参照ください。
マルチパートアップロードには 3 つの API 操作が含まれます。操作の詳細については、次のトピックをご参照ください。
マルチパートアップロードイベントをキャンセルするために使用される API 操作の詳細については、「AbortMultipartUpload」をご参照ください。
アップロードされたパートをリスト表示するために使用される API 操作の詳細については、「ListParts」をご参照ください。
進行中のすべてのマルチパートアップロードイベントをリスト表示するために使用される API 操作の詳細については、「ListMultipartUploads」をご参照ください。