

# 멀티파트 업로드를 사용한 객체 복사
<a name="CopyingObjectsMPUapi"></a>

멀티파트 업로드를 통해 객체를 여러 부분의 집합으로 복사할 수 있습니다. 이 섹션의 예제는 멀티파트 업로드 API를 사용하여 5GB보다 큰 객체를 복사하는 방법을 보여 줍니다. 멀티파트 업로드에 대한 내용은 [Amazon S3에서 멀티파트 업로드를 사용한 객체 업로드 및 복사](mpuoverview.md) 섹션을 참조하세요.

멀티파트 업로드 API를 사용하지 않고 단일 작업으로는 5GB보다 작은 객체를 복사할 수 있습니다. AWS Management Console, AWS CLI, REST API 또는 AWS SDK를 사용하여 5GB보다 작은 객체를 복사할 수 있습니다. 자세한 내용은 [객체 복사, 이동, 이름 변경](copy-object.md) 섹션을 참조하세요.

추가 체크섬이 포함된 멀티파트 업로드를 사용하여 객체를 업로드하는 전체 절차는 [튜토리얼: 멀티파트 업로드를 통한 객체 업로드 및 데이터 무결성 확인](tutorial-s3-mpu-additional-checksums.md) 섹션을 참조하세요.

다음 섹션에서는 REST API 또는 AWS SDK를 사용하여 멀티파트 업로드로 객체를 복사하는 방법을 보여줍니다.

## REST API 사용
<a name="CopyingObjctsUsingRESTMPUapi"></a>

*Amazon Simple Storage Service API 참조*의 다음 섹션에서는 멀티파트 업로드를 위한 REST API에 대해 설명합니다. 기존 객체를 복사하려면, 파트 업로드(복사) API를 사용하고 요청에 `x-amz-copy-source` 요청 헤더를 추가하여 소스 객체를 지정합니다.
+ [멀티파트 업로드 시작](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadInitiate.html)
+ [부분 업로드](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadUploadPart.html)
+ [부분 업로드(복사)](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadUploadPartCopy.html)
+ [멀티파트 업로드 완료](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadComplete.html)
+ [멀티파트 업로드 중단](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadAbort.html)
+ [부분 목록 조회](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadListParts.html)
+ [멀티파트 업로드 목록 조회](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadListMPUpload.html)

이러한 API를 사용하여 REST 요청을 만들거나, 제공된 SDK 중 하나를 사용할 수 있습니다. AWS CLI에서 멀티파트 업로드를 사용하는 방법에 대한 자세한 내용은 [AWS CLI 사용](mpu-upload-object.md#UsingCLImpUpload) 단원을 참조하십시오. SDK에 대한 자세한 내용은 [AWS멀티파트 업로드에 대한 SDK 지원](mpuoverview.md#sdksupportformpu)을 참조하십시오.

## AWS SDK 사용
<a name="copy-object-mpu-sdks"></a>

하위 수준 API를 사용하여 객체를 복사하려면 다음을 수행합니다.
+ `AmazonS3Client.initiateMultipartUpload()` 메서드를 호출하여 멀티파트 업로드를 시작합니다.
+ `AmazonS3Client.initiateMultipartUpload()` 메서드가 반환하는 응답 객체에서 업로드 ID를 저장합니다. 이후의 각 파트 업로드 작업에서 이 업로드 ID를 제공합니다.
+ 모든 파트를 복사합니다. 복사해야 하는 각 파트에 대해 `CopyPartRequest` 클래스의 새 인스턴스를 생성합니다. 소스 및 대상 버킷 이름, 소스 및 대상 객체 키, 업로드 ID, 파트의 첫 번째 및 마지막 바이트 위치와 파트 번호 등과 같은 파트 정보를 제공합니다.
+ `AmazonS3Client.copyPart()` 메서드 호출에 대한 응답을 저장합니다. 각 응답에는 업로드된 파트의 파트 번호화 `ETag` 값이 포함되어 있습니다. 멀티파트 업로드를 완료하려면 이러한 정보가 필요합니다.
+ `AmazonS3Client.completeMultipartUpload()` 메서드를 호출하여 복사 작업을 완료합니다.

------
#### [ Java ]

AWS SDK for Java를 통해 멀티파트 업로드를 사용하여 객체를 복사하는 방법의 예는 *Amazon S3 API 참조*의 [Copy part of an object from another object](https://docs.aws.amazon.com/AmazonS3/latest/API/s3_example_s3_UploadPartCopy_section.html)를 참조하세요.

------
#### [ .NET ]

다음 C\$1 예제는 SDK for .NET을 사용하여 5GB보다 큰 Amazon S3 객체를 하나의 소스 위치에서 다른 위치(예: 한 버킷에서 다른 버킷으로)로 복사합니다. 5GB보다 작은 객체를 복사하려면 [AWS SDK 사용](copy-object.md#CopyingObjectsUsingSDKs)에 설명된 단일 작업 복사 프로시저를 사용하십시오. Amazon S3 멀티파트 업로드에 대한 자세한 내용은 [Amazon S3에서 멀티파트 업로드를 사용한 객체 업로드 및 복사](mpuoverview.md) 섹션을 참조하세요.

이 예제에서는 SDK for .NET 멀티파트 업로드 API를 사용하여 S3 버킷 간에 5GB보다 큰 Amazon 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);
            }
        }
    }
}
```

------