멀티파트 업로드를 사용한 객체 복사 - Amazon Simple Storage Service

멀티파트 업로드를 사용한 객체 복사

이 단원의 예제는 멀티파트 업로드 API를 사용하여 5GB보다 큰 객체를 복사하는 방법을 보여 줍니다. 단일 작업으로는 5GB보다 작은 객체를 복사할 수 있습니다. 자세한 내용은 객체 복사 섹션을 참조하세요.

하위 수준 API를 사용하여 객체를 복사하려면 다음을 수행합니다.

  • AmazonS3Client.initiateMultipartUpload() 메서드를 호출하여 멀티파트 업로드를 시작합니다.

  • AmazonS3Client.initiateMultipartUpload() 메서드가 반환하는 응답 객체에서 업로드 ID를 저장합니다. 이후의 각 파트 업로드 작업에서 이 업로드 ID를 제공합니다.

  • 모든 파트를 복사합니다. 복사해야 하는 각 파트에 대해 CopyPartRequest 클래스의 새 인스턴스를 생성합니다. 소스 및 대상 버킷 이름, 소스 및 대상 객체 키, 업로드 ID, 파트의 첫 번째 및 마지막 바이트 위치와 파트 번호 등과 같은 파트 정보를 제공합니다.

  • AmazonS3Client.copyPart() 메서드 호출에 대한 응답을 저장합니다. 각 응답에는 업로드된 파트의 파트 번호화 ETag 값이 포함되어 있습니다. 멀티파트 업로드를 완료하려면 이러한 정보가 필요합니다.

  • AmazonS3Client.completeMultipartUpload() 메서드를 호출하여 복사 작업을 완료합니다.

Java

다음 예제에서는 Amazon S3 하위 수준 Java API를 사용하여 멀티파트 복사를 수행하는 방법을 보여줍니다. 실제 예제를 작성 및 테스트하는 방법에 대한 자세한 내용은 Amazon S3 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을 사용하여 5GB보다 큰 Amazon S3 객체를 하나의 소스 위치에서 다른 위치(예: 한 버킷에서 다른 버킷으로)로 복사합니다. 5GB보다 작은 객체를 복사하려면 AWS SDK 사용에 설명된 단일 작업 복사 프로시저를 사용하세요. Amazon S3 멀티파트 업로드에 대한 자세한 내용은 멀티파트 업로드를 사용한 객체 업로드 및 복사 단원을 참조하세요.

이 예제에서는 AWS SDK for .NET 멀티파트 업로드 API를 사용하여 S3 버킷 간에 5GB보다 큰 Amazon S3 객체를 복사하는 방법을 보여 줍니다. SDK 호환성 및 실제 예제를 작성하여 테스트하는 방법에 대한 자세한 내용은 Amazon S3 .NET 코드 예제 실행 단원을 참조하세요.

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); } } } }

Amazon Simple Storage Service API 참조의 다음 섹션에서는 멀티파트 업로드를 위한 REST API에 대해 설명합니다. 기존 객체를 복사하려면, 파트 업로드(복사) API를 사용하고 요청에 x-amz-copy-source 요청 헤더를 추가하여 소스 객체를 지정합니다.

이러한 API를 사용하여 REST 요청을 만들거나, 제공된 SDK 중 하나를 사용할 수 있습니다. AWS CLI에서 멀티파트 업로드를 사용하는 방법에 대한 자세한 내용은 AWS CLI 사용 단원을 참조하세요. SDK에 대한 자세한 내용은 멀티파트 업로드에 대한 AWS SDK 지원을 참조하세요.