マルチパートアップロードを使用したオブジェクトのコピー - Amazon Simple Storage Service

マルチパートアップロードを使用したオブジェクトのコピー

マルチパートアップロードを使用すると、オブジェクトをパートのセットとしてコピーすることができます。このセクションの例は、Multipart Upload API を使用して 5 GB よりも大きいオブジェクトをコピーする方法を示しています。マルチパートアップロードの詳細については、「Amazon S3 でのマルチパートアップロードを使用したオブジェクトのアップロードとコピー」を参照してください。

マルチパートアップロード API を使用せずに、1 回のオペレーションで 5 GB 未満のオブジェクトをコピーできます。AWS Management Console、AWS CLI、REST API、または AWS SDK を使用して、5 GB 未満のオブジェクトをコピーできます。詳細については、「オブジェクトのコピー、移動、名前の変更」を参照してください。

マルチパートアップロードで追加のチェックサムを含むオブジェクトをアップロードするエンドツーエンドの手順については、「チュートリアル: マルチパートアップロードでオブジェクトをアップロードして、データ整合性を検証する」を参照してください。

次のセクションでは、REST API または AWS SDK を使用してマルチパートアップロードでオブジェクトをコピーする方法を示します。

Amazon Simple Storage Service API リファレンスの以下のセクションでは、マルチパートアップロードの REST API について説明しています。既存のオブジェクトをコピーするには、UploadPart (Copy) API を使用し、リクエストに x-amz-copy-source リクエストヘッダーを追加してコピー元オブジェクトを指定します。

これらの API を使用して独自の REST リクエストを作成するか、提供されている SDK のいずれかを使用できます。AWS CLI でマルチパートアップロードを使用する方法の詳細については、AWS CLI の使用 を参照してください。SDK の詳細については、「マルチパートアップロードの AWS SDK サポート」を参照してください。

低レベル API を使用してオブジェクトをコピーするには、次の手順を実行します。

  • AmazonS3Client.initiateMultipartUpload() メソッドを呼び出して、マルチパートアップロードを開始します。

  • AmazonS3Client.initiateMultipartUpload() メソッドから返されたレスポンスオブジェクトのアップロード ID を保存します。このアップロード ID は、パートのアップロードオペレーションごとに指定します。

  • すべてのパートをコピーします。コピーする必要があるパートごとに、CopyPartRequest クラスの新しいインスタンスを作成します。パート情報として、送信元と送信先のバケット名、送信元と送信先のオブジェクトキー、アップロード ID、パートの最初と最後のバイトの場所、パート番号などを指定します。

  • AmazonS3Client.copyPart() メソッド呼び出しのレスポンスを保存します。各レスポンスには、アップロードしたパートの ETag 値とパート番号が含まれています。この情報は、マルチパートアップロードを完了するために必要です。

  • AmazonS3Client.completeMultipartUpload() メソッドを呼び出してコピーオペレーションを完了します。

Java

次の例では、Amazon S3 の下位 Java API を使用してマルチパートコピーを実行する方法を示します。作業サンプルの作成およびテストの手順については、「AWS SDK for Java のデベロッパーガイド」の「使用開始」を参照してください。

import com.amazonaws.AmazonServiceException; import com.amazonaws.SdkClientException; import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.regions.Regions; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3ClientBuilder; import com.amazonaws.services.s3.model.*; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class LowLevelMultipartCopy { public static void main(String[] args) throws IOException { Regions clientRegion = Regions.DEFAULT_REGION; String sourceBucketName = "*** Source bucket name ***"; String sourceObjectKey = "*** Source object key ***"; String destBucketName = "*** Target bucket name ***"; String destObjectKey = "*** Target object key ***"; try { AmazonS3 s3Client = AmazonS3ClientBuilder.standard() .withCredentials(new ProfileCredentialsProvider()) .withRegion(clientRegion) .build(); // Initiate the multipart upload. InitiateMultipartUploadRequest initRequest = new InitiateMultipartUploadRequest(destBucketName, destObjectKey); InitiateMultipartUploadResult initResult = s3Client.initiateMultipartUpload(initRequest); // Get the object size to track the end of the copy operation. GetObjectMetadataRequest metadataRequest = new GetObjectMetadataRequest(sourceBucketName, sourceObjectKey); ObjectMetadata metadataResult = s3Client.getObjectMetadata(metadataRequest); long objectSize = metadataResult.getContentLength(); // Copy the object using 5 MB parts. long partSize = 5 * 1024 * 1024; long bytePosition = 0; int partNum = 1; List<CopyPartResult> copyResponses = new ArrayList<CopyPartResult>(); while (bytePosition < objectSize) { // The last part might be smaller than partSize, so check to make sure // that lastByte isn't beyond the end of the object. long lastByte = Math.min(bytePosition + partSize - 1, objectSize - 1); // Copy this part. CopyPartRequest copyRequest = new CopyPartRequest() .withSourceBucketName(sourceBucketName) .withSourceKey(sourceObjectKey) .withDestinationBucketName(destBucketName) .withDestinationKey(destObjectKey) .withUploadId(initResult.getUploadId()) .withFirstByte(bytePosition) .withLastByte(lastByte) .withPartNumber(partNum++); copyResponses.add(s3Client.copyPart(copyRequest)); bytePosition += partSize; } // Complete the upload request to concatenate all uploaded parts and make the // copied object available. CompleteMultipartUploadRequest completeRequest = new CompleteMultipartUploadRequest( destBucketName, destObjectKey, initResult.getUploadId(), getETags(copyResponses)); s3Client.completeMultipartUpload(completeRequest); System.out.println("Multipart copy complete."); } catch (AmazonServiceException e) { // The call was transmitted successfully, but Amazon S3 couldn't process // it, so it returned an error response. e.printStackTrace(); } catch (SdkClientException e) { // Amazon S3 couldn't be contacted for a response, or the client // couldn't parse the response from Amazon S3. e.printStackTrace(); } } // This is a helper function to construct a list of ETags. private static List<PartETag> getETags(List<CopyPartResult> responses) { List<PartETag> etags = new ArrayList<PartETag>(); for (CopyPartResult response : responses) { etags.add(new PartETag(response.getPartNumber(), response.getETag())); } return etags; } }
.NET

次の C# の例では、AWS SDK for .NET を使用して 5 GB を超える Amazon S3 オブジェクトをコピー元からコピー先 (あるバケットから別のバケットなど) にコピーする方法を示します。5 GB 未満のオブジェクトをコピーするには、1 回のオペレーションでコピーする手順を使用します (AWS SDK の使用 を参照)。Amazon S3 マルチパートアップロードの詳細については、Amazon S3 でのマルチパートアップロードを使用したオブジェクトのアップロードとコピー を参照してください。

この例では、AWS SDK for .NET マルチパートアップロード API を使用して、5 GB を超える Amazon S3 オブジェクトを S3 バケットから別のバケットにコピーする方法を示します。

using Amazon; using Amazon.S3; using Amazon.S3.Model; using System; using System.Collections.Generic; using System.Threading.Tasks; namespace Amazon.DocSamples.S3 { class CopyObjectUsingMPUapiTest { private const string sourceBucket = "*** provide the name of the bucket with source object ***"; private const string targetBucket = "*** provide the name of the bucket to copy the object to ***"; private const string sourceObjectKey = "*** provide the name of object to copy ***"; private const string targetObjectKey = "*** provide the name of the object copy ***"; // Specify your bucket region (an example region is shown). private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2; private static IAmazonS3 s3Client; public static void Main() { s3Client = new AmazonS3Client(bucketRegion); Console.WriteLine("Copying an object"); MPUCopyObjectAsync().Wait(); } private static async Task MPUCopyObjectAsync() { // Create a list to store the upload part responses. List<UploadPartResponse> uploadResponses = new List<UploadPartResponse>(); List<CopyPartResponse> copyResponses = new List<CopyPartResponse>(); // Setup information required to initiate the multipart upload. InitiateMultipartUploadRequest initiateRequest = new InitiateMultipartUploadRequest { BucketName = targetBucket, Key = targetObjectKey }; // Initiate the upload. InitiateMultipartUploadResponse initResponse = await s3Client.InitiateMultipartUploadAsync(initiateRequest); // Save the upload ID. String uploadId = initResponse.UploadId; try { // Get the size of the object. GetObjectMetadataRequest metadataRequest = new GetObjectMetadataRequest { BucketName = sourceBucket, Key = sourceObjectKey }; GetObjectMetadataResponse metadataResponse = await s3Client.GetObjectMetadataAsync(metadataRequest); long objectSize = metadataResponse.ContentLength; // Length in bytes. // Copy the parts. long partSize = 5 * (long)Math.Pow(2, 20); // Part size is 5 MB. long bytePosition = 0; for (int i = 1; bytePosition < objectSize; i++) { CopyPartRequest copyRequest = new CopyPartRequest { DestinationBucket = targetBucket, DestinationKey = targetObjectKey, SourceBucket = sourceBucket, SourceKey = sourceObjectKey, UploadId = uploadId, FirstByte = bytePosition, LastByte = bytePosition + partSize - 1 >= objectSize ? objectSize - 1 : bytePosition + partSize - 1, PartNumber = i }; copyResponses.Add(await s3Client.CopyPartAsync(copyRequest)); bytePosition += partSize; } // Set up to complete the copy. CompleteMultipartUploadRequest completeRequest = new CompleteMultipartUploadRequest { BucketName = targetBucket, Key = targetObjectKey, UploadId = initResponse.UploadId }; completeRequest.AddPartETags(copyResponses); // Complete the copy. CompleteMultipartUploadResponse completeUploadResponse = await s3Client.CompleteMultipartUploadAsync(completeRequest); } catch (AmazonS3Exception e) { Console.WriteLine("Error encountered on server. Message:'{0}' when writing an object", e.Message); } catch (Exception e) { Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message); } } } }