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

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

멀티파트 업로드를 사용하여 프로그래밍 방식으로 단일 객체를 Amazon S3에 업로드할 수 있습니다.

자세한 내용은 다음 섹션을 참조하십시오.

AWS SDK는 멀티파트 업로드를 간소화하는 TransferManager라는 상위 수준 API를 표시합니다. 자세한 내용은 멀티파트 업로드를 사용한 객체 업로드 및 복사 단원을 참조하십시오.

파일 또는 스트림에서 데이터를 업로드할 수 있습니다. 또한 멀티파트 업로드에 사용할 부분 크기, 또는 부분을 업로드할 때 사용할 동시 스레드 수와 같은 고급 옵션을 설정할 수 있습니다. 선택적 객체 속성, 스토리지 클래스 또는 ACL(액세스 제어 목록)도 설정할 수 있습니다. 이러한 고급 옵션은 PutObjectRequestTransferManagerConfiguration 클래스를 사용하여 설정합니다.

가능한 경우, TransferManager는 여러 스레드를 사용하여 단일 객체의 여러 부분을 한 번에 업로드하려고 시도합니다. 고대역폭에서 대용량 콘텐츠를 처리하는 경우 처리량이 크게 증가할 수 있습니다.

파일 업로드 기능 외에도, TransferManager 클래스를 사용하여 진행 중인 멀티파트 업로드를 중지할 수 있습니다. 사용자가 업로드를 시작한 후 완료 또는 중지할 때까지 업로드가 진행 중인 것으로 간주됩니다. TransferManager는 지정된 날짜 및 시간 이전에 시작된 지정된 버킷의 진행 중인 멀티파트 업로드를 모두 중지합니다.

멀티파트 업로드를 일시 중지했다 다시 시작해야 하거나 업로드 중에 파트의 크기를 변경해야 하거나 혹은 데이터 크기를 미리 확인하지 않은 경우 하위 수준 PHP API를 사용합니다. 하위 수준 API 메서드에서 제공하는 추가 기능을 포함하여 멀티파트 업로드에 대한 자세한 내용은 AWS SDK 사용(하위 수준 API) 단원을 참조하십시오.

Java

다음 예제에서는 상위 수준 멀티파트 업로드 Java API(TransferManager 클래스)를 사용하여 객체를 업로드합니다. 실제 예제를 작성 및 테스트하는 방법에 대한 자세한 내용은 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.transfer.TransferManager; import com.amazonaws.services.s3.transfer.TransferManagerBuilder; import com.amazonaws.services.s3.transfer.Upload; import java.io.File; public class HighLevelMultipartUpload { public static void main(String[] args) throws Exception { Regions clientRegion = Regions.DEFAULT_REGION; String bucketName = "*** Bucket name ***"; String keyName = "*** Object key ***"; String filePath = "*** Path for file to upload ***"; try { AmazonS3 s3Client = AmazonS3ClientBuilder.standard() .withRegion(clientRegion) .withCredentials(new ProfileCredentialsProvider()) .build(); TransferManager tm = TransferManagerBuilder.standard() .withS3Client(s3Client) .build(); // TransferManager processes all transfers asynchronously, // so this call returns immediately. Upload upload = tm.upload(bucketName, keyName, new File(filePath)); System.out.println("Object upload started"); // Optionally, wait for the upload to finish before continuing. upload.waitForCompletion(); System.out.println("Object upload 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(); } } }
.NET

S3 버킷에 파일을 업로드하려면 TransferUtility 클래스를 사용합니다. 파일에서 데이터를 업로드할 경우에는 객체의 키 이름을 제공해야 합니다. 제공하지 않으면 API에서는 키 이름에 해당하는 파일 이름을 사용합니다. 스트림에서 데이터를 업로드할 경우에는 객체의 키 이름을 제공해야 합니다.

고급 업로드 옵션(예: 부분 크기, 부분을 동시에 업로드할 때 스레드 수, 메타데이터, 스토리지 클래스 또는 ACL)을 설정하려면 TransferUtilityUploadRequest 클래스를 사용합니다.

다음 C# 예제는 파일을 여러 파트로 나누어 Amazon S3 버킷에 업로드합니다. 다양한 TransferUtility.Upload 오버로드를 사용하여 파일을 업로드하는 방법을 보여줍니다. 업로드에 대해 연속적으로 수행되는 각 호출이 이전 업로드를 대체합니다. 특정 버전의 AWS SDK for .NET와 이 예제의 호환성 및 실제 예제를 작성하여 테스트하는 방법에 대한 지침은 Amazon S3 .NET 코드 예제 실행 단원을 참조하십시오.

using Amazon; using Amazon.S3; using Amazon.S3.Transfer; using System; using System.IO; using System.Threading.Tasks; namespace Amazon.DocSamples.S3 { class UploadFileMPUHighLevelAPITest { private const string bucketName = "*** provide bucket name ***"; private const string keyName = "*** provide a name for the uploaded object ***"; private const string filePath = "*** provide the full path name of the file to upload ***"; // 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); UploadFileAsync().Wait(); } private static async Task UploadFileAsync() { try { var fileTransferUtility = new TransferUtility(s3Client); // Option 1. Upload a file. The file name is used as the object key name. await fileTransferUtility.UploadAsync(filePath, bucketName); Console.WriteLine("Upload 1 completed"); // Option 2. Specify object key name explicitly. await fileTransferUtility.UploadAsync(filePath, bucketName, keyName); Console.WriteLine("Upload 2 completed"); // Option 3. Upload data from a type of System.IO.Stream. using (var fileToUpload = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { await fileTransferUtility.UploadAsync(fileToUpload, bucketName, keyName); } Console.WriteLine("Upload 3 completed"); // Option 4. Specify advanced settings. var fileTransferUtilityRequest = new TransferUtilityUploadRequest { BucketName = bucketName, FilePath = filePath, StorageClass = S3StorageClass.StandardInfrequentAccess, PartSize = 6291456, // 6 MB. Key = keyName, CannedACL = S3CannedACL.PublicRead }; fileTransferUtilityRequest.Metadata.Add("param1", "Value1"); fileTransferUtilityRequest.Metadata.Add("param2", "Value2"); await fileTransferUtility.UploadAsync(fileTransferUtilityRequest); Console.WriteLine("Upload 4 completed"); } 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); } } } }
JavaScript

대용량 파일을 업로드합니다.

import { CreateMultipartUploadCommand, UploadPartCommand, CompleteMultipartUploadCommand, AbortMultipartUploadCommand, S3Client, } from "@aws-sdk/client-s3"; const twentyFiveMB = 25 * 1024 * 1024; export const createString = (size = twentyFiveMB) => { return "x".repeat(size); }; export const main = async () => { const s3Client = new S3Client({}); const bucketName = "test-bucket"; const key = "multipart.txt"; const str = createString(); const buffer = Buffer.from(str, "utf8"); let uploadId; try { const multipartUpload = await s3Client.send( new CreateMultipartUploadCommand({ Bucket: bucketName, Key: key, }), ); uploadId = multipartUpload.UploadId; const uploadPromises = []; // Multipart uploads require a minimum size of 5 MB per part. const partSize = Math.ceil(buffer.length / 5); // Upload each part. for (let i = 0; i < 5; i++) { const start = i * partSize; const end = start + partSize; uploadPromises.push( s3Client .send( new UploadPartCommand({ Bucket: bucketName, Key: key, UploadId: uploadId, Body: buffer.subarray(start, end), PartNumber: i + 1, }), ) .then((d) => { console.log("Part", i + 1, "uploaded"); return d; }), ); } const uploadResults = await Promise.all(uploadPromises); return await s3Client.send( new CompleteMultipartUploadCommand({ Bucket: bucketName, Key: key, UploadId: uploadId, MultipartUpload: { Parts: uploadResults.map(({ ETag }, i) => ({ ETag, PartNumber: i + 1, })), }, }), ); // Verify the output by downloading the file from the Amazon Simple Storage Service (Amazon S3) console. // Because the output is a 25 MB string, text editors might struggle to open the file. } catch (err) { console.error(err); if (uploadId) { const abortCommand = new AbortMultipartUploadCommand({ Bucket: bucketName, Key: key, UploadId: uploadId, }); await s3Client.send(abortCommand); } } };

대용량 파일을 다운로드합니다.

import { GetObjectCommand, S3Client } from "@aws-sdk/client-s3"; import { createWriteStream } from "fs"; const s3Client = new S3Client({}); const oneMB = 1024 * 1024; export const getObjectRange = ({ bucket, key, start, end }) => { const command = new GetObjectCommand({ Bucket: bucket, Key: key, Range: `bytes=${start}-${end}`, }); return s3Client.send(command); }; export const getRangeAndLength = (contentRange) => { const [range, length] = contentRange.split("/"); const [start, end] = range.split("-"); return { start: parseInt(start), end: parseInt(end), length: parseInt(length), }; }; export const isComplete = ({ end, length }) => end === length - 1; // When downloading a large file, you might want to break it down into // smaller pieces. Amazon S3 accepts a Range header to specify the start // and end of the byte range to be downloaded. const downloadInChunks = async ({ bucket, key }) => { const writeStream = createWriteStream( fileURLToPath(new URL(`./${key}`, import.meta.url)) ).on("error", (err) => console.error(err)); let rangeAndLength = { start: -1, end: -1, length: -1 }; while (!isComplete(rangeAndLength)) { const { end } = rangeAndLength; const nextRange = { start: end + 1, end: end + oneMB }; console.log(`Downloading bytes ${nextRange.start} to ${nextRange.end}`); const { ContentRange, Body } = await getObjectRange({ bucket, key, ...nextRange, }); writeStream.write(await Body.transformToByteArray()); rangeAndLength = getRangeAndLength(ContentRange); } }; export const main = async () => { await downloadInChunks({ bucket: "my-cool-bucket", key: "my-cool-object.txt", }); };
Go

업로드 관리자를 사용하여 데이터를 부분으로 나누고 동시에 업로드하여 큰 객체를 업로드합니다.

// BucketBasics encapsulates the Amazon Simple Storage Service (Amazon S3) actions // used in the examples. // It contains S3Client, an Amazon S3 service client that is used to perform bucket // and object actions. type BucketBasics struct { S3Client *s3.Client }
// UploadLargeObject uses an upload manager to upload data to an object in a bucket. // The upload manager breaks large data into parts and uploads the parts concurrently. func (basics BucketBasics) UploadLargeObject(bucketName string, objectKey string, largeObject []byte) error { largeBuffer := bytes.NewReader(largeObject) var partMiBs int64 = 10 uploader := manager.NewUploader(basics.S3Client, func(u *manager.Uploader) { u.PartSize = partMiBs * 1024 * 1024 }) _, err := uploader.Upload(context.TODO(), &s3.PutObjectInput{ Bucket: aws.String(bucketName), Key: aws.String(objectKey), Body: largeBuffer, }) if err != nil { log.Printf("Couldn't upload large object to %v:%v. Here's why: %v\n", bucketName, objectKey, err) } return err }

다운로드 관리자를 사용하여 데이터를 부분으로 나누고 동시에 다운로드하여 큰 객체를 다운로드합니다.

// DownloadLargeObject uses a download manager to download an object from a bucket. // The download manager gets the data in parts and writes them to a buffer until all of // the data has been downloaded. func (basics BucketBasics) DownloadLargeObject(bucketName string, objectKey string) ([]byte, error) { var partMiBs int64 = 10 downloader := manager.NewDownloader(basics.S3Client, func(d *manager.Downloader) { d.PartSize = partMiBs * 1024 * 1024 }) buffer := manager.NewWriteAtBuffer([]byte{}) _, err := downloader.Download(context.TODO(), buffer, &s3.GetObjectInput{ Bucket: aws.String(bucketName), Key: aws.String(objectKey), }) if err != nil { log.Printf("Couldn't download large object from %v:%v. Here's why: %v\n", bucketName, objectKey, err) } return buffer.Bytes(), err }
PHP

이 주제에서는 멀티파트 파일 업로드를 위해 AWS SDK for PHP의 상위 수준 Aws\S3\Model\MultipartUpload\UploadBuilder 클래스를 사용하는 방법을 설명합니다. 이미 AWS SDK for PHP 사용 및 PHP 예제 실행의 지침에 따라 AWS SDK for PHP가 올바르게 설치되어 있다고 가정합니다.

다음은 Amazon S3 버킷에 파일을 업로드하는 PHP 예제입니다. 이 예제는 MultipartUploader 객체에 대한 파라미터를 설정하는 방법을 보여 줍니다.

이 가이드의 PHP 예제 실행에 대한 자세한 내용은 PHP 예제 실행 섹션을 참조하십시오.

require 'vendor/autoload.php'; use Aws\Exception\MultipartUploadException; use Aws\S3\MultipartUploader; use Aws\S3\S3Client; $bucket = '*** Your Bucket Name ***'; $keyname = '*** Your Object Key ***'; $s3 = new S3Client([ 'version' => 'latest', 'region' => 'us-east-1' ]); // Prepare the upload parameters. $uploader = new MultipartUploader($s3, '/path/to/large/file.zip', [ 'bucket' => $bucket, 'key' => $keyname ]); // Perform the upload. try { $result = $uploader->upload(); echo "Upload complete: {$result['ObjectURL']}" . PHP_EOL; } catch (MultipartUploadException $e) { echo $e->getMessage() . PHP_EOL; }
Python

다음 예제에서는 상위 수준 멀티파트 업로드 Python API(TransferManager 클래스)를 사용하여 객체를 업로드합니다.

import sys import threading import boto3 from boto3.s3.transfer import TransferConfig MB = 1024 * 1024 s3 = boto3.resource("s3") class TransferCallback: """ Handle callbacks from the transfer manager. The transfer manager periodically calls the __call__ method throughout the upload and download process so that it can take action, such as displaying progress to the user and collecting data about the transfer. """ def __init__(self, target_size): self._target_size = target_size self._total_transferred = 0 self._lock = threading.Lock() self.thread_info = {} def __call__(self, bytes_transferred): """ The callback method that is called by the transfer manager. Display progress during file transfer and collect per-thread transfer data. This method can be called by multiple threads, so shared instance data is protected by a thread lock. """ thread = threading.current_thread() with self._lock: self._total_transferred += bytes_transferred if thread.ident not in self.thread_info.keys(): self.thread_info[thread.ident] = bytes_transferred else: self.thread_info[thread.ident] += bytes_transferred target = self._target_size * MB sys.stdout.write( f"\r{self._total_transferred} of {target} transferred " f"({(self._total_transferred / target) * 100:.2f}%)." ) sys.stdout.flush() def upload_with_default_configuration( local_file_path, bucket_name, object_key, file_size_mb ): """ Upload a file from a local folder to an Amazon S3 bucket, using the default configuration. """ transfer_callback = TransferCallback(file_size_mb) s3.Bucket(bucket_name).upload_file( local_file_path, object_key, Callback=transfer_callback ) return transfer_callback.thread_info def upload_with_chunksize_and_meta( local_file_path, bucket_name, object_key, file_size_mb, metadata=None ): """ Upload a file from a local folder to an Amazon S3 bucket, setting a multipart chunk size and adding metadata to the Amazon S3 object. The multipart chunk size controls the size of the chunks of data that are sent in the request. A smaller chunk size typically results in the transfer manager using more threads for the upload. The metadata is a set of key-value pairs that are stored with the object in Amazon S3. """ transfer_callback = TransferCallback(file_size_mb) config = TransferConfig(multipart_chunksize=1 * MB) extra_args = {"Metadata": metadata} if metadata else None s3.Bucket(bucket_name).upload_file( local_file_path, object_key, Config=config, ExtraArgs=extra_args, Callback=transfer_callback, ) return transfer_callback.thread_info def upload_with_high_threshold(local_file_path, bucket_name, object_key, file_size_mb): """ Upload a file from a local folder to an Amazon S3 bucket, setting a multipart threshold larger than the size of the file. Setting a multipart threshold larger than the size of the file results in the transfer manager sending the file as a standard upload instead of a multipart upload. """ transfer_callback = TransferCallback(file_size_mb) config = TransferConfig(multipart_threshold=file_size_mb * 2 * MB) s3.Bucket(bucket_name).upload_file( local_file_path, object_key, Config=config, Callback=transfer_callback ) return transfer_callback.thread_info def upload_with_sse( local_file_path, bucket_name, object_key, file_size_mb, sse_key=None ): """ Upload a file from a local folder to an Amazon S3 bucket, adding server-side encryption with customer-provided encryption keys to the object. When this kind of encryption is specified, Amazon S3 encrypts the object at rest and allows downloads only when the expected encryption key is provided in the download request. """ transfer_callback = TransferCallback(file_size_mb) if sse_key: extra_args = {"SSECustomerAlgorithm": "AES256", "SSECustomerKey": sse_key} else: extra_args = None s3.Bucket(bucket_name).upload_file( local_file_path, object_key, ExtraArgs=extra_args, Callback=transfer_callback ) return transfer_callback.thread_info def download_with_default_configuration( bucket_name, object_key, download_file_path, file_size_mb ): """ Download a file from an Amazon S3 bucket to a local folder, using the default configuration. """ transfer_callback = TransferCallback(file_size_mb) s3.Bucket(bucket_name).Object(object_key).download_file( download_file_path, Callback=transfer_callback ) return transfer_callback.thread_info def download_with_single_thread( bucket_name, object_key, download_file_path, file_size_mb ): """ Download a file from an Amazon S3 bucket to a local folder, using a single thread. """ transfer_callback = TransferCallback(file_size_mb) config = TransferConfig(use_threads=False) s3.Bucket(bucket_name).Object(object_key).download_file( download_file_path, Config=config, Callback=transfer_callback ) return transfer_callback.thread_info def download_with_high_threshold( bucket_name, object_key, download_file_path, file_size_mb ): """ Download a file from an Amazon S3 bucket to a local folder, setting a multipart threshold larger than the size of the file. Setting a multipart threshold larger than the size of the file results in the transfer manager sending the file as a standard download instead of a multipart download. """ transfer_callback = TransferCallback(file_size_mb) config = TransferConfig(multipart_threshold=file_size_mb * 2 * MB) s3.Bucket(bucket_name).Object(object_key).download_file( download_file_path, Config=config, Callback=transfer_callback ) return transfer_callback.thread_info def download_with_sse( bucket_name, object_key, download_file_path, file_size_mb, sse_key ): """ Download a file from an Amazon S3 bucket to a local folder, adding a customer-provided encryption key to the request. When this kind of encryption is specified, Amazon S3 encrypts the object at rest and allows downloads only when the expected encryption key is provided in the download request. """ transfer_callback = TransferCallback(file_size_mb) if sse_key: extra_args = {"SSECustomerAlgorithm": "AES256", "SSECustomerKey": sse_key} else: extra_args = None s3.Bucket(bucket_name).Object(object_key).download_file( download_file_path, ExtraArgs=extra_args, Callback=transfer_callback ) return transfer_callback.thread_info

AWS SDK는 멀티파트 업로드를 위해 Amazon S3 REST API와 매우 유사한 하위 수준 API를 표시합니다(멀티파트 업로드를 사용한 객체 업로드 및 복사 참조). 멀티파트 업로드를 일시 중지한 후 다시 시작해야 하거나 업로드 중에 부분 크기를 변경해야 하거나 업로드 데이터 크기를 미리 확인하지 않은 경우 하위 수준 API를 사용합니다. 이러한 요구 사항이 없는 경우에는 상위 수준 API를 사용합니다(AWS SDK 사용(상위 수준 API) 참조).

Java

다음 예제에서는 하위 수준 Java 클래스를 사용하여 파일을 업로드하는 방법을 보여 줍니다. 여기에서는 다음 단계를 수행합니다.

  • AmazonS3Client.initiateMultipartUpload() 메서드를 사용하여 멀티파트 업로드를 시작하고, InitiateMultipartUploadRequest 객체를 전달합니다.

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

  • 객체의 파트를 업로드합니다. 각 파트에 대해 AmazonS3Client.uploadPart() 메서드를 호출합니다. UploadPartRequest 객체를 사용하여 파트 업로드 정보를 제공합니다.

  • 각 파트에 대해 AmazonS3Client.uploadPart() 메서드의 응답에서 얻은 ETag를 목록에 저장합니다. ETag 값을 사용하여 멀티파트 업로드를 완료합니다.

  • AmazonS3Client.completeMultipartUpload() 메서드를 호출하여 멀티파트 업로드를 완료합니다.

실제 예제를 작성 및 테스트하는 방법에 대한 자세한 내용은 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.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class LowLevelMultipartUpload { public static void main(String[] args) throws IOException { Regions clientRegion = Regions.DEFAULT_REGION; String bucketName = "*** Bucket name ***"; String keyName = "*** Key name ***"; String filePath = "*** Path to file to upload ***"; File file = new File(filePath); long contentLength = file.length(); long partSize = 5 * 1024 * 1024; // Set part size to 5 MB. try { AmazonS3 s3Client = AmazonS3ClientBuilder.standard() .withRegion(clientRegion) .withCredentials(new ProfileCredentialsProvider()) .build(); // Create a list of ETag objects. You retrieve ETags for each object part // uploaded, // then, after each individual part has been uploaded, pass the list of ETags to // the request to complete the upload. List<PartETag> partETags = new ArrayList<PartETag>(); // Initiate the multipart upload. InitiateMultipartUploadRequest initRequest = new InitiateMultipartUploadRequest(bucketName, keyName); InitiateMultipartUploadResult initResponse = s3Client.initiateMultipartUpload(initRequest); // Upload the file parts. long filePosition = 0; for (int i = 1; filePosition < contentLength; i++) { // Because the last part could be less than 5 MB, adjust the part size as // needed. partSize = Math.min(partSize, (contentLength - filePosition)); // Create the request to upload a part. UploadPartRequest uploadRequest = new UploadPartRequest() .withBucketName(bucketName) .withKey(keyName) .withUploadId(initResponse.getUploadId()) .withPartNumber(i) .withFileOffset(filePosition) .withFile(file) .withPartSize(partSize); // Upload the part and add the response's ETag to our list. UploadPartResult uploadResult = s3Client.uploadPart(uploadRequest); partETags.add(uploadResult.getPartETag()); filePosition += partSize; } // Complete the multipart upload. CompleteMultipartUploadRequest compRequest = new CompleteMultipartUploadRequest(bucketName, keyName, initResponse.getUploadId(), partETags); s3Client.completeMultipartUpload(compRequest); } 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(); } } }
.NET

다음은 하위 수준 AWS SDK for .NET 멀티파트 업로드 API를 사용하여 S3 버킷에 파일을 업로드하는 방법을 보여주는 C# 예제입니다. Amazon S3 멀티파트 업로드에 대한 자세한 내용은 멀티파트 업로드를 사용한 객체 업로드 및 복사 단원을 참조하십시오.

참고

AWS SDK for .NET API를 사용하여 대용량 객체를 업로드하는 경우 요청 스트림에 데이터를 기록하는 중 시간 초과가 발생할 수 있습니다. UploadPartRequest를 사용하여 제한 시간을 명시적으로 설정할 수 있습니다.

다음은 하위 수준 멀티파트 업로드 API를 사용하여 S3 버킷에 파일을 업로드하는 C# 예제입니다. 특정 버전의 AWS SDK for .NET와 이 예제의 호환성 및 실제 예제를 작성하여 테스트하는 방법에 대한 지침은 Amazon S3 .NET 코드 예제 실행 단원을 참조하십시오.

using Amazon; using Amazon.Runtime; using Amazon.S3; using Amazon.S3.Model; using System; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; namespace Amazon.DocSamples.S3 { class UploadFileMPULowLevelAPITest { private const string bucketName = "*** provide bucket name ***"; private const string keyName = "*** provide a name for the uploaded object ***"; private const string filePath = "*** provide the full path name of the file to upload ***"; // 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("Uploading an object"); UploadObjectAsync().Wait(); } private static async Task UploadObjectAsync() { // Create list to store upload part responses. List<UploadPartResponse> uploadResponses = new List<UploadPartResponse>(); // Setup information required to initiate the multipart upload. InitiateMultipartUploadRequest initiateRequest = new InitiateMultipartUploadRequest { BucketName = bucketName, Key = keyName }; // Initiate the upload. InitiateMultipartUploadResponse initResponse = await s3Client.InitiateMultipartUploadAsync(initiateRequest); // Upload parts. long contentLength = new FileInfo(filePath).Length; long partSize = 5 * (long)Math.Pow(2, 20); // 5 MB try { Console.WriteLine("Uploading parts"); long filePosition = 0; for (int i = 1; filePosition < contentLength; i++) { UploadPartRequest uploadRequest = new UploadPartRequest { BucketName = bucketName, Key = keyName, UploadId = initResponse.UploadId, PartNumber = i, PartSize = partSize, FilePosition = filePosition, FilePath = filePath }; // Track upload progress. uploadRequest.StreamTransferProgress += new EventHandler<StreamTransferProgressArgs>(UploadPartProgressEventCallback); // Upload a part and add the response to our list. uploadResponses.Add(await s3Client.UploadPartAsync(uploadRequest)); filePosition += partSize; } // Setup to complete the upload. CompleteMultipartUploadRequest completeRequest = new CompleteMultipartUploadRequest { BucketName = bucketName, Key = keyName, UploadId = initResponse.UploadId }; completeRequest.AddPartETags(uploadResponses); // Complete the upload. CompleteMultipartUploadResponse completeUploadResponse = await s3Client.CompleteMultipartUploadAsync(completeRequest); } catch (Exception exception) { Console.WriteLine("An AmazonS3Exception was thrown: { 0}", exception.Message); // Abort the upload. AbortMultipartUploadRequest abortMPURequest = new AbortMultipartUploadRequest { BucketName = bucketName, Key = keyName, UploadId = initResponse.UploadId }; await s3Client.AbortMultipartUploadAsync(abortMPURequest); } } public static void UploadPartProgressEventCallback(object sender, StreamTransferProgressArgs e) { // Process event. Console.WriteLine("{0}/{1}", e.TransferredBytes, e.TotalBytes); } } }
PHP

이 주제는 AWS SDK for PHP 버전 3에서 하위 수준 uploadPart 메서드를 사용하여 파일을 여러 부분으로 업로드하는 방법을 보여 줍니다. 이미 AWS SDK for PHP 사용 및 PHP 예제 실행의 지침에 따라 AWS SDK for PHP가 올바르게 설치되어 있다고 가정합니다.

다음은 하위 수준 PHP API 멀티파트 업로드를 사용하여 Amazon S3 버킷에 파일을 업로드하는 PHP 예제입니다. 이 가이드의 PHP 예제 실행에 대한 자세한 내용은 PHP 예제 실행 섹션을 참조하십시오.

require 'vendor/autoload.php'; use Aws\S3\Exception\S3Exception; use Aws\S3\S3Client; $bucket = '*** Your Bucket Name ***'; $keyname = '*** Your Object Key ***'; $filename = '*** Path to and Name of the File to Upload ***'; $s3 = new S3Client([ 'version' => 'latest', 'region' => 'us-east-1' ]); $result = $s3->createMultipartUpload([ 'Bucket' => $bucket, 'Key' => $keyname, 'StorageClass' => 'REDUCED_REDUNDANCY', 'Metadata' => [ 'param1' => 'value 1', 'param2' => 'value 2', 'param3' => 'value 3' ] ]); $uploadId = $result['UploadId']; // Upload the file in parts. try { $file = fopen($filename, 'r'); $partNumber = 1; while (!feof($file)) { $result = $s3->uploadPart([ 'Bucket' => $bucket, 'Key' => $keyname, 'UploadId' => $uploadId, 'PartNumber' => $partNumber, 'Body' => fread($file, 5 * 1024 * 1024), ]); $parts['Parts'][$partNumber] = [ 'PartNumber' => $partNumber, 'ETag' => $result['ETag'], ]; $partNumber++; echo "Uploading part $partNumber of $filename." . PHP_EOL; } fclose($file); } catch (S3Exception $e) { $result = $s3->abortMultipartUpload([ 'Bucket' => $bucket, 'Key' => $keyname, 'UploadId' => $uploadId ]); echo "Upload of $filename failed." . PHP_EOL; } // Complete the multipart upload. $result = $s3->completeMultipartUpload([ 'Bucket' => $bucket, 'Key' => $keyname, 'UploadId' => $uploadId, 'MultipartUpload' => $parts, ]); $url = $result['Location']; echo "Uploaded $filename to $url." . PHP_EOL;

AWS SDK for Ruby 버전 3은 Amazon S3 멀티파트 업로드를 두 가지 방법으로 지원합니다. 첫 번째 옵션으로 관리형 파일 업로드를 사용할 수 있습니다. 자세한 내용은 AWS 개발자 블로그에서 Amazon S3에 파일 업로드를 참조하십시오. 관리형 파일 업로드는 파일을 버킷에 업로드하는 데 권장되는 방법입니다. 관리형 파일 업로드에는 다음과 같은 이점이 있습니다.

  • 15MB를 초과하는 객체에 대해 멀티파트 업로드를 관리합니다.

  • 인코딩 문제를 방지하기 위해 이진 모드에서 파일을 올바로 엽니다.

  • 대형 객체의 부분 업로드에 대한 여러 스레드를 병렬로 사용합니다.

또는 다음의 멀티파트 업로드 클라이언트 작업을 직접 사용할 수 있습니다.

  • create_multipart_upload – 멀티파트 업로드를 시작하고 업로드 ID를 반환합니다.

  • upload_part – 멀티파트 업로드에서 파트를 업로드합니다.

  • upload_part_copy – 기존 객체에서 데이터를 복사하여 파트를 데이터 원본으로 업로드합니다.

  • complete_multipart_upload – 이전에 업로드된 파트를 어셈블하여 멀티파트 업로드를 완료합니다.

  • abort_multipart_upload – 멀티파트 업로드를 중단합니다.

자세한 내용은 AWS SDK for Ruby 버전 3 사용 단원을 참조하십시오.

Amazon Simple Storage Service API 참조의 다음 섹션에서는 멀티파트 업로드를 위한 REST API에 대해 설명합니다.

AWS Command Line Interface(AWS CLI)의 다음 섹션에서는 멀티파트 업로드를 위한 작업을 설명합니다.

또한, REST API를 사용하여 REST 요청을 만들거나, AWS SDK 중 하나를 사용할 수 있습니다. REST API에 대한 자세한 내용은 REST API 사용 단원을 참조하십시오. SDK에 대한 자세한 내용은 멀티파트 업로드를 사용한 객체 업로드을 참조하세요.