

# 디렉터리 버킷의 객체 작업
<a name="directory-buckets-objects"></a>

Amazon S3 디렉터리 버킷을 생성한 후에는 Amazon S3 콘솔, AWS Command Line Interface(AWS CLI), AWS SDK를 사용하여 객체 작업을 할 수 있습니다.

디렉터리 버킷에서 대량 작업 수행, 객체 가져오기, 업로드, 복사, 삭제, 다운로드에 대한 자세한 내용은 다음 주제를 참조하세요.

**Topics**
+ [디렉터리 버킷으로 객체 가져오기](create-import-job.md)
+ [디렉터리 버킷의 S3 수명 주기 작업](directory-buckets-objects-lifecycle.md)
+ [디렉터리 버킷에 배치 작업 사용](directory-buckets-objects-Batch-Ops.md)
+ [디렉터리 버킷의 객체에 데이터 추가](directory-buckets-objects-append.md)
+ [디렉터리 버킷의 객체 이름 바꾸기](directory-buckets-objects-rename.md)
+ [디렉터리 버킷에 객체 업로드](directory-buckets-objects-upload.md)
+ [디렉터리 버킷에서 또는 디렉터리 버킷에 객체 복사](directory-buckets-objects-copy.md)
+ [디렉터리 버킷에서 객체 삭제](directory-bucket-delete-object.md)
+ [디렉터리 버킷에서 객체 다운로드](directory-buckets-objects-GetExamples.md)
+ [객체 디렉터리 버킷을 공유하기 위해 미리 서명된 URL 생성](directory-buckets-objects-generate-presigned-url-Examples.md)
+ [디렉터리 버킷에서 객체 메타데이터 검색](directory-buckets-objects-HeadObjectExamples.md)
+ [디렉터리 버킷에서 객체 나열](directory-buckets-objects-listobjectsExamples.md)

# 디렉터리 버킷으로 객체 가져오기
<a name="create-import-job"></a>

Amazon S3에서 디렉터리 버킷을 생성한 후 가져오기 작업을 사용하여 새 버킷에 데이터를 채울 수 있습니다. 가져오기는 범용 버킷에서 디렉터리 버킷으로 객체를 복사하는 S3 배치 작업 건을 생성하는 간소화된 방법입니다.

**참고**  
가져오기 작업에는 다음과 같은 제한 사항이 적용됩니다.  
소스 버킷과 대상 버킷은 같은 AWS 리전 및 계정에 있어야 합니다.
소스 버킷은 디렉터리 버킷이 될 수 없습니다.
5GB보다 큰 객체는 지원되지 않으며 복사 작업에서 생략됩니다.
Glacier Flexible Retrival, Glacier Deep Archive, Intelligent-Tiering Archive Access 계층 및 Intelligent-Tiering Deep Archive 계층 스토리지 클래스의 객체는 먼저 복원해야 가져올 수 있습니다.
MD5 체크섬 알고리즘을 사용하여 가져온 객체는 CRC32 체크섬을 사용하도록 변환됩니다.
가져온 객체는 범용 버킷에서 사용하는 스토리지 클래스와는 요금 구조가 다른 Express One Zone 스토리지 클래스를 사용합니다. 다수의 객체를 가져올 때는 이러한 비용 차이를 고려하세요.

가져오기 작업을 구성할 때는 기존 객체를 복사할 소스 버킷 또는 접두사를 지정합니다. 또한 소스 객체에 액세스할 수 있는 권한이 있는 AWS Identity and Access Management(IAM) 역할을 제공합니다. 그러면 Amazon S3가 객체를 복사하고 적절한 스토리지 클래스와 체크섬 설정을 자동으로 적용하는 배치 작업 건을 시작합니다.

가져오기 작업을 구성하려면 Amazon S3 콘솔을 사용합니다.

## Amazon S3 콘솔 사용
<a name="create-import-job-console-procedure"></a>

**디렉터리 버킷으로 객체를 가져오는 방법**

1. AWS Management Console에 로그인한 후 [https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/)에서 S3 콘솔을 엽니다.

1. 왼쪽 탐색 창에서 **버킷**을 선택하고 **디렉터리** 버킷 탭을 선택합니다. 객체를 가져올 대상 디렉터리 버킷 옆에 있는 옵션 버튼을 선택합니다.

1. **가져오기**를 선택합니다.

1. **소스**에는 가져오려는 객체가 들어 있는 범용 버킷(또는 접두사를 포함한 버킷 경로)을 입력합니다. 목록에서 기존의 범용 버킷을 선택하려면 **S3 찾아보기**를 선택합니다.

1. **소스 객체 액세스 및 복사 권한**의 경우 다음 중 하나를 수행하여 소스 객체를 가져오는 데 필요한 권한을 가진 IAM 역할을 지정합니다.
   + Amazon S3가 대신 새 IAM 역할을 생성하도록 허용하려면 **새 IAM 역할 생성**을 선택합니다.
   + 목록에서 기존 IAM 역할을 선택하려면 **기존 IAM 역할에서 선택**을 선택합니다.
   + Amazon 리소스 이름(ARN)을 입력하여 기존 IAM 역할을 지정하려면 **IAM 역할 ARN 입력**을 선택한 다음 해당 필드에 ARN을 입력합니다.

1. **대상** 및 **복사된 객체 설정** 섹션에 표시된 정보를 검토합니다. **대상** 섹션의 정보가 정확하면 **가져오기**를 선택하여 복사 작업을 시작합니다.

   Amazon S3 콘솔은 **배치 작업** 페이지에 새 작업의 상태를 표시합니다. 작업에 대한 자세한 내용을 보려면 작업 이름 옆의 옵션 버튼을 선택한 다음 **작업** 메뉴에서 **세부 정보 보기**를 선택합니다. 객체를 가져올 대상 디렉터리 버킷을 열려면 **가져오기 대상 보기**를 선택합니다.

# 디렉터리 버킷의 S3 수명 주기 작업
<a name="directory-buckets-objects-lifecycle"></a>

 S3 수명 주기는 사용자 대신 만료된 객체를 삭제하여 디렉터리 버킷의 S3 Express One Zone에 객체를 비용 효율적으로 저장하는 데 도움이 됩니다. 객체의 수명 주기를 관리하려면 디렉터리 버킷에 대한 S3 수명 주기 구성을 만듭니다. S3 수명 주기 구성은 Amazon S3이 객체 그룹에 적용하는 작업을 정의하는 일련의 규칙입니다. AWS Command Line Interface(AWS CLI), AWS SDK, Amazon S3 REST API 및 AWS CloudFormation을 사용하여 디렉터리 버킷에서 Amazon S3 수명 주기 구성을 설정할 수 있습니다.

수명 주기 구성에서 규칙을 사용하여 객체에 대해 Amazon S3가 수행할 작업을 정의합니다. 디렉터리 버킷에 저장된 객체의 경우 수명 주기 규칙을 생성하여 객체가 오래되면 만료할 수 있습니다. 또한 수명 주기 규칙을 생성하여 디렉터리 버킷에서 매일 불완전한 멀티파트 업로드를 삭제할 수 있습니다.

버킷에 수명 주기 구성을 추가할 경우 구성 규칙이 기존 객체는 물론 나중에 추가하는 객체에도 적용됩니다. 예를 들어 특정 접두사가 있는 객체를 생성한 후 30일이 경과하면 만료시키는 만료 작업을 포함하는 수명 주기 구성 규칙을 오늘 추가할 경우, S3는 30일 이상 경과하고 해당 접두사가 있는 모든 기존 객체를 삭제 대기열에 넣습니다.

## 디렉터리 버킷에 대한 S3 수명 주기의 차이점
<a name="directory-bucket-lifecycle-differences"></a>

디렉터리 버킷의 객체의 경우 객체를 만료시키고 불완전한 멀티파트 업로드를 삭제하는 수명 주기 규칙을 생성할 수 있습니다. 그러나 디렉터리 버킷의 S3 수명 주기는 스토리지 클래스 간 전환 작업을 지원하지 않습니다.

**CreateSession**

수명 주기는 퍼블릭 `DeleteObject` 및 `DeleteObjects` API 작업을 사용하여 디렉터리 버킷의 객체를 만료시킵니다. 해당 API 작업을 사용하기 위해 S3 수명 주기는 `CreateSession` API를 사용하여 임시 보안 자격 증명을 설정하고 디렉터리 버킷의 객체에 액세스합니다. 자세한 내용은 [*Amazon S3 API 참조*의 `CreateSession`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateSession.html) 섹션을 참조하세요.

수명 주기 보안 주체에 대한 삭제 권한을 거부하는 활성 정책이 있을 경우 S3 수명 주기가 사용자를 대신하여 객체 삭제를 차단합니다.

### 버킷 정책을 사용하여 S3 수명 주기 서비스 보안 주체에 권한 부여
<a name="lifecycle-directory-bucket-policy"></a>

다음 버킷 정책은 S3 수명 주기 서비스 위탁자에게 `DeleteObject` 및 `DeleteObjects`와 같은 작업을 수행하기 위한 세션을 생성할 수 있는 권한을 부여합니다. `CreateSession` 요청에서 세션 모드가 지정되지 않으면, 세션은 권한 설정에 따라 허용되는 최대 권한으로 생성됩니다(먼저 `ReadWrite`를 시도하고, `ReadWrite`가 허용되지 않으면 `ReadOnly`를 시도). 그러나 `ReadOnly` 세션은 객체를 수정하거나 삭제하는 수명 주기 작업에는 충분하지 않습니다. 따라서 이 예제에서는 `s3express:SessionMode` 조건 키를 사용하여 `ReadWrite` 세션 모드를 명시적으로 지정합니다.

**Example - 수명 주기 작업에 대해 명시적 `ReadWrite` 세션 모드를 사용한 `CreateSession` 직접 호출을 허용하는 버킷 정책**  

```
 { 
   "Version":"2008-10-17",		 	 	  
   "Statement":[
      {
         "Effect":"Allow",
         "Principal": {
            "Service":"lifecycle.s3.amazonaws.com"
          },
          "Action":"s3express:CreateSession", 
          "Condition": { 
             "StringEquals": {
                "s3express:SessionMode": "ReadWrite"
              }
           }, 
           "Resource":"arn:aws:s3express:us-east-2:412345678921:bucket/amzn-s3-demo-bucket--use2-az2--x-s3"
       }
   ] 
}
```

### 수명 주기 규칙 모니터링
<a name="lifecycle-directory-bucket-monitoring"></a>

디렉터리 버킷에 저장된 객체의 경우 S3 수명 주기는 AWS CloudTrail 관리 및 데이터 이벤트 로그를 생성합니다. 자세한 내용은 [S3 Express One Zone에 대한 CloudTrail 로그 파일 예시](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-log-files.html)를 참조하세요.

수명 주기 구성을 생성하고 S3 수명 주기 관련 문제를 해결하는 방법에 대한 자세한 내용은 다음 주제를 참조하세요.

**Topics**

# 디렉터리 버킷에 대한 수명 주기 구성 생성 및 관리
<a name="directory-bucket-create-lc"></a>

AWS Command Line Interface(AWS CLI), AWS SDK, REST API를 사용하여 디렉터리 버킷에 대한 수명 주기 구성을 만들 수 있습니다.

## AWS CLI 사용
<a name="set-lifecycle-config-cli"></a>

다음 AWS CLI 명령을 사용하여 S3 수명 주기 구성을 관리할 수 있습니다.
+ `put-bucket-lifecycle-configuration`
+ `get-bucket-lifecycle-configuration`
+ `delete-bucket-lifecycle`

AWS CLI 설정에 대한 지침은 **Amazon S3 API 참조의 [AWS CLI를 사용하여 Amazon S3에서 개발](https://docs.aws.amazon.com/AmazonS3/latest/API/setup-aws-cli.html)을 참조하세요.

Amazon S3 수명 주기 구성은 XML 파일입니다. 그러나 AWS CLI를 사용할 때는 XML 형식을 지정할 수 없으며 대신 JSON 형식을 지정해야 합니다. 다음은 XML 수명 주기 구성과 AWS CLI 명령에서 지정할 수 있는 그에 상응하는 JSON 구성의 예시입니다.

다음 AWS CLI 예시에서는 수명 주기 구성 정책을 디렉터리 버킷에 적용합니다. 이 정책은 플래그가 지정된 접두사(myprefix)가 있고 정의된 개체 크기인 모든 개체가 7일 후에 만료되도록 지정합니다. 이 예제를 사용하려면 각 *user input placeholder*를 사용자의 정보로 대체합니다.

수명 주기 구성 정책을 JSON 파일로 저장합니다. 이 예에서는 lifecycle1.json으로 파일 이름을 지정합니다.

**Example**  

```
{
    "Rules": [
        {
        "Expiration": {
            "Days": 7
        },
        "ID": "Lifecycle expiration rule",
        "Filter": {
            "And": {
                "Prefix": "myprefix/",
                "ObjectSizeGreaterThan": 500,
                "ObjectSizeLessThan": 64000
            }
        },
        "Status": "Enabled"
    }
    ]
}
```
`put-bucket-lifecycle-configuration` CLI 명령의 일부로 JSON 파일을 제출합니다. 이 명령을 사용하려면 각 *사용자 입력 자리 표시자*를 사용자의 정보로 대체합니다.  

```
aws s3api put-bucket-lifecycle-configuration --region us-west-2 --profile default --bucket amzn-s3-demo-bucket--usw2-az1--x-s3 --lifecycle-configuration file://lc-policy.json --checksum-algorithm crc32c 
```

**Example**  

```
<LifecycleConfiguration>
    <Rule>
        <ID>Lifecycle expiration rule</ID>
        <Filter>
            <And>
                <Prefix>myprefix/</Prefix>
                <ObjectSizeGreaterThan>500</ObjectSizeGreaterThan>
                <ObjectSizeLessThan>64000</ObjectSizeLessThan>
            </And>
        </Filter>
        <Status>Enabled</Status>     
        <Expiration>
             <Days>7</Days>
        </Expiration>
    </Rule>
</LifecycleConfiguration>
```

## AWS SDK 사용
<a name="directory-bucket-upload-sdks"></a>

------
#### [ SDK for Java ]

**Example**  

```
import software.amazon.awssdk.services.s3.model.PutBucketLifecycleConfigurationRequest;
import software.amazon.awssdk.services.s3.model.PutBucketLifecycleConfigurationResponse;
import software.amazon.awssdk.services.s3.model.ChecksumAlgorithm;
import software.amazon.awssdk.services.s3.model.BucketLifecycleConfiguration;
import software.amazon.awssdk.services.s3.model.LifecycleRule;
import software.amazon.awssdk.services.s3.model.LifecycleRuleFilter;
import software.amazon.awssdk.services.s3.model.LifecycleExpiration;
import software.amazon.awssdk.services.s3.model.LifecycleRuleAndOperator;
import software.amazon.awssdk.services.s3.model.GetBucketLifecycleConfigurationResponse;
import software.amazon.awssdk.services.s3.model.GetBucketLifecycleConfigurationRequest;
import software.amazon.awssdk.services.s3.model.DeleteBucketLifecycleRequest;
import software.amazon.awssdk.services.s3.model.DeleteBucketLifecycleResponse;
import software.amazon.awssdk.services.s3.model.AbortIncompleteMultipartUpload;

// PUT a Lifecycle policy
LifecycleRuleFilter objectExpirationFilter = LifecycleRuleFilter.builder().and(LifecycleRuleAndOperator.builder().prefix("dir1/").objectSizeGreaterThan(3L).objectSizeLessThan(20L).build()).build();
LifecycleRuleFilter mpuExpirationFilter = LifecycleRuleFilter.builder().prefix("dir2/").build();
       
LifecycleRule objectExpirationRule = LifecycleRule.builder().id("lc").filter(objectExpirationFilter).status("Enabled").expiration(LifecycleExpiration.builder()
                    .days(10)
                    .build())
                .build();
LifecycleRule mpuExpirationRule = LifecycleRule.builder().id("lc-mpu").filter(mpuExpirationFilter).status("Enabled").abortIncompleteMultipartUpload(AbortIncompleteMultipartUpload.builder()
                        .daysAfterInitiation(10)
                        .build())
                .build();
        
PutBucketLifecycleConfigurationRequest putLifecycleRequest = PutBucketLifecycleConfigurationRequest.builder()
                .bucket("amzn-s3-demo-bucket--usw2-az1--x-s3")
                .checksumAlgorithm(ChecksumAlgorithm.CRC32)
                .lifecycleConfiguration(
                        BucketLifecycleConfiguration.builder()
                                .rules(objectExpirationRule, mpuExpirationRule)
                                .build()
                ).build();

PutBucketLifecycleConfigurationResponse resp = client.putBucketLifecycleConfiguration(putLifecycleRequest);

// GET the Lifecycle policy 
GetBucketLifecycleConfigurationResponse getResp = client.getBucketLifecycleConfiguration(GetBucketLifecycleConfigurationRequest.builder().bucket("amzn-s3-demo-bucket--usw2-az1--x-s3").build());

// DELETE the Lifecycle policy
DeleteBucketLifecycleResponse delResp = client.deleteBucketLifecycle(DeleteBucketLifecycleRequest.builder().bucket("amzn-s3-demo-bucket--usw2-az1--x-s3").build());
```

------
#### [ SDK for Go ]

**Example**  

```
package main

import (
    "context"
    "log"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "github.com/aws/aws-sdk-go-v2/service/s3/types"
)
// PUT a Lifecycle policy
func putBucketLifecycleConfiguration(client *s3.Client, bucketName string ) error {
    lifecycleConfig := &s3.PutBucketLifecycleConfigurationInput{
        Bucket: aws.String(bucketName),
        LifecycleConfiguration: &types.BucketLifecycleConfiguration{
            Rules: []types.LifecycleRule{
                {
                    ID:     aws.String("lc"),
                    Filter: &types.LifecycleRuleFilter{
                        And: &types.LifecycleRuleAndOperator{
                            Prefix: aws.String("foo/"), 
                            ObjectSizeGreaterThan: aws.Int64(1000000), 
                            ObjectSizeLessThan:    aws.Int64(100000000), 
                            },
                        },
                    
                    Status: types.ExpirationStatusEnabled,
                    Expiration: &types.LifecycleExpiration{
                        Days: aws.Int32(int32(1)), 
                    },
                },
                {
                    ID:     aws.String("abortmpu"),
                    Filter: &types.LifecycleRuleFilter{
                        Prefix: aws.String("bar/"), 
                    },
                    Status: types.ExpirationStatusEnabled,
                    AbortIncompleteMultipartUpload: &types.AbortIncompleteMultipartUpload{
                        DaysAfterInitiation: aws.Int32(int32(5)), 
                    },
                },
            },
        },
    }
    _, err := client.PutBucketLifecycleConfiguration(context.Background(), lifecycleConfig)
    return err
}
// Get the Lifecycle policy
func getBucketLifecycleConfiguration(client *s3.Client, bucketName string) error {
    getLifecycleConfig := &s3.GetBucketLifecycleConfigurationInput{
        Bucket: aws.String(bucketName),
    }

    resp, err := client.GetBucketLifecycleConfiguration(context.Background(), getLifecycleConfig)
    if err != nil {
        return err
    }
    return nil
}
// Delete the Lifecycle policy
func deleteBucketLifecycleConfiguration(client *s3.Client, bucketName string) error {
    deleteLifecycleConfig := &s3.DeleteBucketLifecycleInput{
        Bucket: aws.String(bucketName),
    }
    _, err := client.DeleteBucketLifecycle(context.Background(), deleteLifecycleConfig)
    return err
}
func main() {
    cfg, err := config.LoadDefaultConfig(context.Background(), config.WithRegion("us-west-2")) // Specify your region here
    if err != nil {
        log.Fatalf("unable to load SDK config, %v", err)
    }
    s3Client := s3.NewFromConfig(cfg)
    bucketName := "amzn-s3-demo-bucket--usw2-az1--x-s3" 
    putBucketLifecycleConfiguration(s3Client, bucketName)
    getBucketLifecycleConfiguration(s3Client, bucketName)
    deleteBucketLifecycleConfiguration(s3Client, bucketName)
    getBucketLifecycleConfiguration(s3Client, bucketName)
}
```

------
#### [ SDK for .NET ]

**Example**  

```
using Amazon;
using Amazon.S3;
using Amazon.S3.Model;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Amazon.DocSamples.S3
{
    class LifecycleTest
    {
        private const string bucketName = "amzn-s3-demo-bucket--usw2-az1--x-s3";
        // Specify your bucket region (an example region is shown).
        private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2;
        private static IAmazonS3 client;
        public static void Main()
        {
            client = new AmazonS3Client(bucketRegion);
            AddUpdateDeleteLifecycleConfigAsync().Wait();
        }

        private static async Task AddUpdateDeleteLifecycleConfigAsync()
        {
            try
            {
                var lifeCycleConfiguration = new LifecycleConfiguration()
                {
                    Rules = new List <LifecycleRule>
                        {
                            new LifecycleRule
                            {
                                 Id = "delete rule",
                                  Filter = new LifecycleFilter()
                                 {
                                     LifecycleFilterPredicate = new LifecyclePrefixPredicate()
                                     {
                                         Prefix = "projectdocs/"
                                     }
                                 },
                                 Status = LifecycleRuleStatus.Enabled,
                                 Expiration = new LifecycleRuleExpiration()
                                 {
                                       Days = 10
                                 }
                            }
                        }
                };

                // Add the configuration to the bucket. 
                await AddExampleLifecycleConfigAsync(client, lifeCycleConfiguration);

                // Retrieve an existing configuration. 
                lifeCycleConfiguration = await RetrieveLifecycleConfigAsync(client);

                // Add a new rule.
                lifeCycleConfiguration.Rules.Add(new LifecycleRule
                {
                    Id = "mpu abort rule",
                    Filter = new LifecycleFilter()
                    {
                        LifecycleFilterPredicate = new LifecyclePrefixPredicate()
                        {
                            Prefix = "YearlyDocuments/"
                        }
                    },
                    Expiration = new LifecycleRuleExpiration()
                    {
                        Days = 10
                    },
                    AbortIncompleteMultipartUpload = new LifecycleRuleAbortIncompleteMultipartUpload()
                    {
                        DaysAfterInitiation = 10
                    }
                });

                // Add the configuration to the bucket. 
                await AddExampleLifecycleConfigAsync(client, lifeCycleConfiguration);

                // Verify that there are now two rules.
                lifeCycleConfiguration = await RetrieveLifecycleConfigAsync(client);
                Console.WriteLine("Expected # of rulest=2; found:{0}", lifeCycleConfiguration.Rules.Count);

                // Delete the configuration.
                await RemoveLifecycleConfigAsync(client);

                // Retrieve a nonexistent configuration.
                lifeCycleConfiguration = await RetrieveLifecycleConfigAsync(client);

            }
            catch (AmazonS3Exception e)
            {
                Console.WriteLine("Error encountered ***. 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);
            }
        }

        static async Task AddExampleLifecycleConfigAsync(IAmazonS3 client, LifecycleConfiguration configuration)
        {

            PutLifecycleConfigurationRequest request = new PutLifecycleConfigurationRequest
            {
                BucketName = bucketName,
                Configuration = configuration
            };
            var response = await client.PutLifecycleConfigurationAsync(request);
        }

        static async Task <LifecycleConfiguration> RetrieveLifecycleConfigAsync(IAmazonS3 client)
        {
            GetLifecycleConfigurationRequest request = new GetLifecycleConfigurationRequest
            {
                BucketName = bucketName
            };
            var response = await client.GetLifecycleConfigurationAsync(request);
            var configuration = response.Configuration;
            return configuration;
        }

        static async Task RemoveLifecycleConfigAsync(IAmazonS3 client)
        {
            DeleteLifecycleConfigurationRequest request = new DeleteLifecycleConfigurationRequest
            {
                BucketName = bucketName
            };
            await client.DeleteLifecycleConfigurationAsync(request);
        }
    }
}
```

------
#### [ SDK for Python ]

**Example**  

```
import boto3

client = boto3.client("s3", region_name="us-west-2")
bucket_name = 'amzn-s3-demo-bucket--usw2-az1--x-s3'

client.put_bucket_lifecycle_configuration(
    Bucket=bucket_name,
    ChecksumAlgorithm='CRC32',
    LifecycleConfiguration={
        'Rules': [
            {
                'ID': 'lc',
                'Filter': {
                    'And': {
                        'Prefix': 'foo/',
                        'ObjectSizeGreaterThan': 1000000,
                        'ObjectSizeLessThan': 100000000,
                    }
                },
                'Status': 'Enabled',
                'Expiration': {
                    'Days': 1
                }
            },
            {
                'ID': 'abortmpu',
                'Filter': {
                    'Prefix': 'bar/'
                },
                'Status': 'Enabled',
                'AbortIncompleteMultipartUpload': {
                    'DaysAfterInitiation': 5
                }
            }
        ]
    }
)

result = client.get_bucket_lifecycle_configuration(
    Bucket=bucket_name
)

client.delete_bucket_lifecycle(
    Bucket=bucket_name
)
```

------

# 디렉터리 버킷의 S3 수명 주기 문제 해결
<a name="directory-buckets-lifecycle-troubleshooting"></a>

**Topics**
+ [수명 주기 구성을 설정했지만 디렉터리 버킷의 객체가 만료되지 않음](#troubleshoot-directory-bucket-lifecycle-1)
+ [수명 주기 규칙에 따라 취해진 조치를 모니터링하려면 어떻게 해야 하나요?](#troubleshoot-directory-bucket-lifecycle-2)

## 수명 주기 구성을 설정했지만 디렉터리 버킷의 객체가 만료되지 않음
<a name="troubleshoot-directory-bucket-lifecycle-1"></a>

디렉터리 버킷의 S3 수명 주기는 퍼블릭 API를 사용하여 S3 Express One Zone에서 객체를 삭제합니다. 객체 수준 퍼블릭 API를 사용하려면 `CreateSession`에 권한을 부여하고 객체를 삭제하는 S3 수명 주기 권한을 허용해야 합니다. 삭제를 거부하는 활성 정책이 있을 경우 S3 수명 주기가 사용자를 대신하여 객체 삭제를 차단합니다.

버킷 정책을 올바르게 구성하여 삭제하려는 객체가 만료될 수 있도록 해야 합니다. CloudTrail에서 `CreateSession` API 간접 호출을 위한 `AccessDenied` 추적용 AWS CloudTrail 로그를 확인하여 액세스가 거부되었는지 여부를 확인할 수 있습니다. CloudTrail 로그를 확인하면 액세스 문제를 해결하고 액세스 거부 오류의 근본 원인을 식별하는 데 도움이 될 수 있습니다. 그런 다음, 관련 정책을 업데이트하여 잘못된 액세스 제어를 수정할 수 있습니다.

버킷 정책이 올바르게 설정되어 있지만 문제가 지속될 경우 수명 주기 규칙을 검토하여 적절한 객체 하위 집합에 적용되는지 확인하는 것이 좋습니다.

## 수명 주기 규칙에 따라 취해진 조치를 모니터링하려면 어떻게 해야 하나요?
<a name="troubleshoot-directory-bucket-lifecycle-2"></a>

 AWS CloudTrail 데이터 이벤트 로그를 사용하여 디렉터리 버킷에서 S3 수명 주기가 수행한 작업을 모니터링할 수 있습니다. 자세한 내용은 [CloudTrail 로그 파일 예제](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-log-files.html)를 참조하세요.

# 디렉터리 버킷에 배치 작업 사용
<a name="directory-buckets-objects-Batch-Ops"></a>

Amazon S3 배치 작업을 사용하여 S3 버킷에 저장된 객체에 대해 작업을 수행할 수 있습니다. S3 배치 작업에 대한 자세한 내용은 [Amazon S3 객체에 대한 대규모 배치 작업 수행](https://docs.aws.amazon.com/AmazonS3/latest/userguide/batch-ops.html)을 참조하세요.

다음 항목에서는 디렉터리 버킷의 S3 Express One Zone 스토리지 클래스에 대한 배치 작업 수행에 관해 설명합니다.

**Topics**
+ [디렉터리 버킷에 배치 작업 사용](#UsingBOPsDirectoryBuckets)
+ [주요 차이점](#UsingBOPsDirectoryBucketsKeyDiffs)

## 디렉터리 버킷에 배치 작업 사용
<a name="UsingBOPsDirectoryBuckets"></a>

디렉터리 버킷에 저장된 객체에 대해 **복사** 작업과 **AWS Lambda 함수 호출** 작업을 수행할 수 있습니다. **복사**를 사용하면 같은 유형의 버킷 간에 객체를 복사할 수 있습니다(예: 디렉터리 버킷에서 디렉터리 버킷으로). 디렉터리 버킷과 범용 버킷 간에 객체를 복사할 수도 있습니다. **AWS Lambda 함수 호출**을 사용하면 Lambda 함수를 사용하여 직접 정의한 코드로 디렉터리 버킷의 객체에 대한 작업을 수행할 수 있습니다.

**객체 복사**  
동일한 버킷 유형 간에 또는 디렉터리 버킷과 범용 버킷 간에 객체를 복사할 수 있습니다. 디렉터리 버킷으로 복사할 때는 이 버킷 유형에 맞는 Amazon 리소스 이름(ARN) 형식을 사용해야 합니다. 디렉터리 버킷의 ARN 형식은 `arn:aws:s3express:region:account-id:bucket/bucket-base-name--x-s3`입니다.

**참고**  
소스 또는 대상 버킷이 AWS 로컬 영역에 있는 경우 다른 AWS 리전에 객체를 복사할 수 없습니다. 소스 버킷과 대상 버킷의 상위 AWS 리전이 동일해야 합니다. 소스 버킷과 대상 버킷은 서로 다른 버킷 위치 유형(가용 영역 또는 로컬 영역)일 수 있습니다.

S3 콘솔에서 **가져오기** 작업을 사용하여 디렉터리 버킷에 데이터를 채울 수도 있습니다. **가져오기**는 범용 버킷에서 디렉터리 버킷으로 객체를 복사하는 배치 작업 건을 생성하는 간소화된 방법입니다. 범용 버킷에서 디렉터리 버킷으로의 **가져오기** 복사 작업의 경우 S3는 매니페스트를 자동으로 생성합니다. 자세한 내용은 [디렉터리 버킷으로 객체 가져오기](https://docs.aws.amazon.com/AmazonS3/latest/userguide/create-import-job.html) 및 [매니페스트 지정](https://docs.aws.amazon.com/AmazonS3/latest/userguide/specify-batchjob-manifest.html)을 참조하세요.

**Lambda 함수 호출(`LambdaInvoke`)**  
배치 작업을 사용하여 디렉터리 버킷에서 작동하는 Lambda 함수를 호출하려면 특별한 요구 사항이 있습니다. 예를 들어, v2 JSON 호출 체계를 사용하여 Lambda 요청을 구조화하고 작업 생성 시 InvocationSchemaVersion 2.0을 지정해야 합니다. 자세한 내용은 [AWS Lambda 함수 호출](https://docs.aws.amazon.com/AmazonS3/latest/userguide/batch-ops-invoke-lambda.html)을 참조하세요.

## 주요 차이점
<a name="UsingBOPsDirectoryBucketsKeyDiffs"></a>

다음은 대량 작업을 사용하여 디렉터리 버킷에 저장된 오브젝트에 대한 대량 작업을 수행할 때 S3 Express One Zone 스토리지 클래스가 있는 경우의 주요 차이점 목록입니다.
+ 디렉터리 버킷의 경우 SSE-S3 및 AWS Key Management Service(AWS KMS) 키(SSE-KMS)를 사용한 서버 측 암호화가 지원됩니다. 디렉터리 버킷(소스 또는 대상)에서 고객 제공 키(SSE-C)를 사용한 서버 측 암호화를 사용하도록 지정하는 `CopyObject` 요청을 하면 응답에 HTTP `400 (Bad Request)` 오류가 반환됩니다.

  버킷의 기본 암호화는 원하는 암호화 구성을 사용하고 `CreateSession` 요청 또는 `PUT` 객체 요청에서 버킷 기본 암호화를 재정의하지 않는 것이 좋습니다. 그러면 새 객체가 원하는 암호화 설정으로 자동 암호화됩니다. 디렉터리 버킷의 암호화 재정의 동작 및 SSE-KMS를 사용하여 디렉터리 버킷의 새 객체 사본을 암호화하는 방법에 대한 자세한 내용은 [Specifying server-side encryption with AWS KMS for new object uploads](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-specifying-kms-encryption.html)를 참조하세요.

  [배치 운영의 Copy 작업을 통해](#directory-buckets-objects-Batch-Ops) SSE-KMS로 암호화된 객체를 범용 버킷에서 디렉터리 버킷으로, 디렉터리 버킷에서 범용 버킷으로 또는 디렉터리 버킷 간에 복사하는 경우 S3 버킷 키는 지원되지 않습니다. 이 경우 Amazon S3는 KMS 암호화 개체에 대한 사본 요청이 있을 때마다 AWS KMS를 직접적으로 호출합니다. 디렉터리 버킷에서 SSE-KMS를 사용하는 방법에 대한 자세한 내용은 [디렉터리 버킷의 기본 암호화 설정 및 모니터링](s3-express-bucket-encryption.md) 및 [디렉터리 버킷에서 AWS KMS 키(SSE-KMS)를 사용한 서버 측 암호화 사용](s3-express-UsingKMSEncryption.md) 섹션을 참조하세요.
+ 디렉터리 버킷의 객체에는 태그를 지정할 수 없습니다. 빈 태그 세트만 지정할 수 있습니다. 기본적으로 배치 작업은 태그를 복사합니다. 태그가 있는 객체를 범용 버킷과 디렉터리 버킷 간에 복사하면 `501 (Not Implemented)` 응답이 표시됩니다.
+ S3 Express One Zone은 업로드 또는 다운로드 중에 데이터를 검증하는 데 사용하는 체크섬 알고리즘을 선택할 수 있는 옵션을 제공합니다. SHA(보안 해시 알고리즘) 또는 CRC(순환 중복 검사) 데이터 무결성 확인 알고리즘(CRC32, SHA-1, SHA-256) 중 하나를 선택할 수 있습니다. MD5 기반 체크섬은 S3 Express One Zone 스토리지 클래스에서 지원되지 않습니다.
+ 기본적으로 모든 Amazon S3 버킷은 객체 소유권 설정을 S3 버킷 소유자 적용으로 설정하며 액세스 제어 목록(ACL)이 비활성화되어 있습니다. 디렉터리 버킷의 경우 이 설정을 수정할 수 없습니다. 범용 버킷의 객체를 디렉터리 버킷으로 복사할 수 있습니다. 하지만 디렉터리 버킷으로 복사하거나 디렉터리 버킷에서 복사할 때는 기본 ACL을 덮어쓸 수 없습니다.
+ 매니페스트를 지정하는 방법과 관계없이 목록 자체는 범용 버킷에 저장해야 합니다. 배치 작업은 디렉터리 버킷에서 기존 매니페스트를 가져오거나 생성된 매니페스트를 디렉터리 버킷에 저장할 수 없습니다. 하지만 매니페스트에 설명된 객체는 디렉터리 버킷에 저장할 수 있습니다.
+ 배치 작업은 S3 인벤토리 보고서에서 디렉터리 버킷을 위치로 지정할 수 없습니다. 인벤토리 보고서는 디렉터리 버킷을 지원하지 않습니다. `ListObjectsV2` API 작업을 사용하여 객체를 나열하여 디렉터리 버킷 내의 객체에 대한 매니페스트 파일을 만들 수 있습니다. 그런 다음 CSV 파일로 목록을 삽입할 수 있습니다.

### 액세스 권한 부여
<a name="BOPsAccess"></a>

 복사 작업을 수행하려면 다음 권한이 있어야 합니다.
+ 한 디렉터리 버킷에서 다른 디렉터리 버킷으로 객체를 복사하려면 `s3express:CreateSession` 권한이 있어야 합니다.
+ 디렉터리 버킷에서 범용 버킷으로 객체를 복사하려면 대상 버킷에 객체 사본을 쓸 수 있도록 `s3express:CreateSession` 권한과 `s3:PutObject` 권한이 있어야 합니다.
+ 범용 버킷에서 디렉터리 버킷으로 객체를 복사하려면 복사되는 소스 객체를 읽을 수 있도록 `s3express:CreateSession` 권한과 `s3:GetObject` 권한이 있어야 합니다.

   자세한 내용은 *Amazon Simple Storage Service API 참조*에서 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html)를 참조하세요.
+ Lambda 함수를 호출하려면 Lambda 함수를 기반으로 리소스에 권한을 부여해야 합니다. 필요한 권한을 확인하려면 해당 API 권한을 확인하세요.

# 디렉터리 버킷의 객체에 데이터 추가
<a name="directory-buckets-objects-append"></a>

디렉터리 버킷의 S3 Express One Zone 스토리지 클래스에 저장된 기존 객체의 끝에 데이터를 추가할 수 있습니다. 일정 기간 동안 지속적으로 데이터를 작성하거나 객체에 작성하는 동안 객체를 읽어야 할 경우 객체에 데이터를 추가하는 기능을 사용하는 것이 좋습니다. 객체에 데이터를 추가하는 작업은 로그 파일에 새 로그 항목을 추가하거나 트랜스코딩 후 스트리밍될 때 비디오 파일에 새 비디오 세그먼트를 추가하는 등의 사용 사례에서 흔히 볼 수 있습니다. 객체에 데이터를 추가하면 기존에는 로컬 스토리지에 데이터를 결합한 후 최종 객체를 Amazon S3에 복사했던 애플리케이션을 간소화할 수 있습니다.

객체에 추가할 수 있는 데이터에 대한 최소 크기 요구 사항은 없습니다. 그러나 단일 요청에서 객체에 추가할 수 있는 데이터의 최대 크기는 5GB입니다. 이는 Amazon S3 API를 사용하여 데이터를 업로드할 경우의 최대 요청 크기와 한도가 같습니다.

각 추가 작업이 성공하면 객체의 일부를 생성하며 각 객체에는 최대 10,000개의 파트가 있을 수 있습니다. 다시 말해 최대 10,000번까지 객체에 데이터를 추가할 수 있습니다. S3 멀티파트 업로드를 사용하여 객체를 생성할 경우 업로드된 각 파트는 총 최대 10,000개의 파트에 포함됩니다. 예를 들어 파트 1,000개로 구성된 멀티파트 업로드로 생성된 객체에 최대 9,000번 추가할 수 있습니다.

**참고**  
 파트 한도에 도달하면 [TooManyParts](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html#API_PutObject_Errors) 오류가 발생합니다. `CopyObject` API를 사용하여 횟수를 재설정할 수 있습니다.

 파트를 객체에 병렬로 업로드하고 파트가 업로드되는 동안 파트를 읽을 필요가 없을 경우 Amazon S3 멀티파트 업로드를 사용하는 것이 좋습니다. 자세한 내용은 [멀티파트 업로드 사용](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-using-multipart-upload.html)을 참조하세요.

객체에 대한 데이터 추가는 S3 Express One Zone 스토리지 클래스에 저장된 디렉터리 버킷의 객체에 대해서만 지원됩니다. S3 Express One Zone에 대한 자세한 내용은 [S3 Express One Zone 시작하기](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-getting-started.html)를 참조하세요.

AWS SDK, AWS CLI 및 `PutObject` API를 사용하여 디렉터리 버킷의 객체에 데이터를 추가할 수 있습니다. `PutObject` 요청을 할 때 `x-amz-write-offset-bytes` 헤더를 추가할 객체의 크기로 설정합니다. `PutObject` API 작업을 사용하려면 `CreateSession` API를 사용하여 디렉터리 버킷의 객체에 액세스하기 위한 임시 보안 자격 증명을 설정해야 합니다. 자세한 내용은 *Amazon S3 API Reference*의 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) 및 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateSession.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateSession.html) 섹션을 참조하세요.

성공적인 각 추가 작업은 `PutObject` 요청으로 청구됩니다. 자세한 가격 책정 정보는 [https://aws.amazon.com/s3/pricing/](https://aws.amazon.com/s3/pricing/) 섹션을 참조하세요.

**참고**  
1.12 릴리스부터 Mountpoint for Amazon S3는 S3 Express One Zone에 저장된 객체에 데이터 추가를 지원합니다. 시작하려면 `--incremental-upload ` 플래그를 설정하여 옵트인해야 합니다. Mountpoint에 대한 자세한 내용은 [Mountpoint 작업](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mountpoint.html)을 참조하세요.

 추가된 데이터를 업로드하는 동안 CRC(순환 중복 검사) 알고리즘을 사용할 경우 `HeadObject` 또는 `GetObject` 요청을 사용하여 전체 객체 CRC 기반 체크섬을 검색할 수 있습니다. 추가된 데이터를 업로드하는 동안 SHA-1 또는 SHA-256 알고리즘을 사용할 경우 추가된 파트의 체크섬을 검색하고 이전 PutObject 응답에서 반환된 SHA 체크섬을 사용하여 무결성을 확인할 수 있습니다. 자세한 내용은 [데이터 보호 및 암호화](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-data-protection.html.html)를 참조하세요.

## AWS CLI, AWS SDK 및 REST API를 사용하여 객체에 데이터 추가
<a name="directory-bucket-append"></a>

AWS Command Line Interface(AWS CLI), AWS SDK 및 REST API를 사용하여 객체에 데이터를 추가할 수 있습니다.

### AWS CLI 사용
<a name="set-append--cli"></a>

다음 `put-object` 예시 명령은 AWS CLI를 사용하여 객체에서 데이터를 추가할 수 있는 방법을 보여줍니다. 이 명령을 실행하려면 *user input placeholders*를 사용자의 정보로 대체합니다.

```
aws s3api put-object --bucket amzn-s3-demo-bucket--azid--x-s3 --key sampleinput/file001.bin --body bucket-seed/file001.bin --write-offset-bytes size-of-sampleinput/file001.bin
```

### AWS SDK 사용
<a name="directory-bucket-append-sdks"></a>

------
#### [ SDK for Java ]

AWS SDK for Java를 사용하여 객체에 데이터를 추가할 수 있습니다.

```
var putObjectRequestBuilder = PutObjectRequest.builder()
                                              .key(key)
                                              .bucket(bucketName)
                                              .writeOffsetBytes(9);
var response = s3Client.putObject(putObjectRequestBuilder.build());
```

------
#### [ SDK for Python ]

```
s3.put_object(Bucket='amzn-s3-demo-bucket--use2-az2--x-s3', Key='2024-11-05-sdk-test', Body=b'123456789', WriteOffsetBytes=9)
```

------

### REST API 사용
<a name="directory-bucket-append-api"></a>

 객체에 데이터를 추가하기 위해 REST 요청을 보낼 수 있습니다. [자세한 내용은 `PutObject` 단원을 참조하세요.](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html#API_PutObject)

# 디렉터리 버킷의 객체 이름 바꾸기
<a name="directory-buckets-objects-rename"></a>

`RenameObject` 작업을 사용하면 데이터 이동 없이 S3 Express One Zone 스토리지 클래스를 사용하는 디렉터리 버킷의 기존 객체 이름을 원자적으로 바꿀 수 있습니다. 기존 객체의 이름을 소스로 지정하고 객체의 새 이름을 동일한 디렉터리 버킷 내의 대상으로 지정하여 객체의 이름을 바꿀 수 있습니다. 슬래시(`/`) 구분 기호 문자로 끝나는 객체에서는 `RenameObject` API 작업이 성공하지 못합니다. 자세한 내용은 [Amazon S3 객체 이름 지정](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html)을 참조하세요.

`RenameObject` 작업은 일반적으로 객체 크기와 관계없이 몇 밀리초 내에 완료됩니다. 이 기능은 로그 파일 관리, 미디어 처리 및 데이터 분석과 같은 애플리케이션을 가속화합니다. 또한 `RenameObject`는 스토리지 클래스, 암호화 유형, 생성 날짜, 마지막 수정 날짜 및 체크섬 속성을 포함한 모든 객체 메타데이터 속성을 보존합니다.

**참고**  
`RenameObject`는 S3 Express One Zone 스토리지 클래스에 저장된 객체에 대해서만 지원됩니다.

 `RenameObject` 작업에 대한 액세스 권한을 부여하려면 세션 기반 권한 부여를 위해 `CreateSession` 작업을 사용하는 것이 좋습니다. 특히 버킷 정책 또는 ID 기반 정책에서 디렉터리 버킷에 `s3express:CreateSession` 권한을 부여합니다. 그런 다음, 디렉터리 버킷에서 `CreateSession` API 직접 호출을 수행하여 세션 토큰을 가져옵니다. 요청 헤더에 세션 토큰을 포함하여 이 작업에 API 요청을 할 수 있습니다. 세션 토큰이 만료되면 다른 `CreateSession` API 직접 호출을 수행하여 사용할 새 세션 토큰을 생성합니다. AWS CLI 및 AWS SDK는 세션이 만료될 때 서비스 중단을 방지하기 위해 세션 토큰을 자동으로 새로 고치는 등 세션을 생성하고 관리합니다. 권한 부여에 대한 자세한 내용은 *Amazon S3 API 참조*의 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateSession.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateSession.html) 섹션을 참조하세요. 영역 엔드포인트 API 작업에 대한 자세한 내용은 [`CreateSession`을 사용하여 영역 엔드포인트 API 작업 권한 부여](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-create-session.html)를 참조하세요.

 기존 객체를 덮어쓰지 않으려면 `RenameObject` 요청에 `‘*’` 값과 함께 `If-None-Match` 조건부 헤더를 추가하면 됩니다. 객체 이름이 이미 있는 경우 Amazon S3에서 `412 Precondition Failed` 오류를 반환합니다. 자세한 내용은 **Amazon S3 API 참조의 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_RenameObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_RenameObject.html) 섹션을 참조하세요.

 `RenameObject`는 AWS CloudTrail에 로깅되는 영역 엔드포인트 API 작업(객체 수준 또는 데이터 플레인 작업)입니다. CloudTrail을 사용하여 디렉터리 버킷의 객체에 대해 수행된 `RenameObject` 작업에 대한 정보를 수집할 수 있습니다. 자세한 내용은 [AWS CloudTrail로 디렉터리 버킷에 로그인](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-one-zone-logging.html) 및 [디렉터리 버킷에 대한 CloudTrail 로그 파일 예제](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-log-files.html)를 참조하세요.

S3 Express One Zone은 `RenameObject`를 지원하는 유일한 스토리지 클래스이며, S3 Express One Zone에서의 `PUT`, `COPY`, `POST` 및 `LIST` 요청과 가격이 동일합니다(요청 1,000개당). 자세한 내용은 [Amazon S3 요금](https://aws.amazon.com/s3/pricing/)을 참조하세요.

## 객체 이름 바꾸기
<a name="directory-bucket-rename"></a>

디렉터리 버킷의 객체 이름을 바꾸려면 Amazon S3 콘솔, AWS CLI, AWS SDK, REST API 또는 Mountpoint for Amazon S3(버전 1.19.0 이상)를 사용하면 됩니다.

### S3 콘솔 사용
<a name="set-rename--console"></a>

**디렉터리 버킷의 객체 이름을 바꾸는 방법**

1. AWS Management Console에 로그인한 후 [https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/)에서 S3 콘솔을 엽니다.

1. 탐색 창에서 **버킷**을 선택하고 **디렉터리 버킷** 탭을 선택합니다. 이름을 바꿀 객체가 포함된 Amazon S3 디렉터리 버킷으로 이동합니다.

1. 이름을 바꾸려는 객체의 확인란을 선택합니다.

1. **작업** 메뉴에서 **객체 이름 바꾸기**를 선택합니다.

1. **새 객체 이름** 상자에 객체의 새 이름을 입력합니다.
**참고**  
기존 객체와 동일한 객체 이름을 지정하면 작업이 실패하고 Amazon S3가 `412 Precondition Failed` 오류를 반환합니다. 객체 키 이름 길이는 1,024바이트를 초과할 수 없습니다. 객체 이름에 포함된 접두사는 총 길이에 포함됩니다.

1. **객체 이름 바꾸기**를 선택합니다. Amazon S3가 객체의 이름을 바꿉니다.

### AWS CLI 사용
<a name="set-rename--cli"></a>

`rename-object` 예시에서는 AWS CLI를 사용하여 객체의 이름을 바꾸는 방법을 보여줍니다. 이러한 명령을 실행하려면 *사용자 입력 자리 표시자*를 실제 정보로 대체합니다.

다음 예시에서는 소스 객체의 ETag에 대한 조건부 검사를 사용하여 객체의 이름을 바꾸는 방법을 보여줍니다.

```
aws s3api rename-object \                                    
    --bucket amzn-s3-demo-bucket--usw2-az1--x-s3 \
    --key new-file.txt \
    --rename-source original-file.txt \
    --source-if-match "\"a1b7c3d2e5f6\""
```

이 명령은 다음 작업을 수행합니다.
+ *amzn-s3-demo-bucket--usw2-az1--x-s3* 디렉터리 버킷에서 객체 이름을 *original-file.txt*에서 *new-file.txt*로 바꿉니다.
+ 소스 객체의 ETag가 '*a1b7c3d4e5f6*'과 일치하는 경우에만 이름 변경을 수행합니다.

ETag가 일치하지 않으면 `412 Precondition Failed` 오류와 함께 작업이 실패합니다.

다음 예시에서는 새로 지정된 객체 이름에 대한 조건부 검사를 통해 객체의 이름을 바꾸는 방법을 보여줍니다.

```
aws s3api rename-object \
    --bucket amzn-s3-demo-bucket--usw2-az1--x-s3 \
    --key new-file.txt \
    --rename-source amzn-s3-demo-bucket--usw2-az1--x-s3/original-file.txt \
    --destination-if-none-match "\"e5f3g7h8i9j0\""
```

이 명령은 다음 작업을 수행합니다.
+ *amzn-s3-demo-bucket--usw2-az1--x-s3* 디렉터리 버킷에서 객체 이름을 *original-file.txt*에서 *new-file.txt*로 바꿉니다.
+ 객체가 존재하고 객체의 ETag가 '*e5f3g7h8i9j0*'과 일치하지 않는 경우에만 이름 바꾸기 작업을 수행합니다.

새 이름이 지정되어 있고 ETag가 일치하는 객체가 이미 있는 경우 `412 Precondition Failed` 오류와 함께 작업이 실패합니다.

### AWS SDK 사용
<a name="directory-bucket-rename-sdks"></a>

------
#### [ SDK for Java ]

AWS SDK for Java를 사용하여 객체의 이름을 바꿀 수 있습니다. 이러한 예시를 사용하려면 *사용자 입력 자리 표시자*를 실제 정보로 대체하세요.

다음 예시는 AWS SDK for Java를 사용하여 `RenameObjectRequest`를 생성하는 방법을 보여줍니다.

```
String key = "key";
String newKey = "new-key";
String expectedETag = "e5f3g7h8i9j0";
RenameObjectRequest renameRequest = RenameObjectRequest.builder()
    .bucket(amzn-s3-demo-bucket--usw2-az1--x-s3)
    .key(newKey)
    .renameSource(key)
    .destinationIfMatch(e5f3g7h8i9j0)
    .build();
```

이 코드는 다음을 수행합니다.
+ *amzn-s3-demo-bucket--usw2-az1--x-s3* 디렉터리 버킷에서 객체 이름을 '*key*'에서 '*new-key*'로 바꾸는 요청을 생성합니다.
+ 객체의 ETag가 '*e5f3g7h8i9j0*'과 일치하는 경우에만 이름 바꾸기가 발생한다는 조건을 포함합니다.
+ ETag가 일치하지 않거나 객체가 존재하지 않으면 작업이 실패합니다.

다음 예시에서는 AWS SDK for Java를 사용하여 일치하지 않는 조건으로 `RenameObjectRequest`를 생성하는 방법을 보여줍니다.

```
String key = "key";
String newKey = "new-key";
String noneMatchETag = "e5f3g7h8i9j0";
RenameObjectRequest renameRequest = RenameObjectRequest.builder()
    .bucket(amzn-s3-demo-bucket--usw2-az1--x-s3)
    .key(newKey)
    .renameSource(key)
    .destinationIfNoneMatch(noneMatchETag)
    .build();
```

이 코드는 다음을 수행합니다.
+ *amzn-s3-demo-bucket--usw2-az1--x-s3* 디렉터리 버킷에서 객체 이름을 '*key*'에서 '*new-key*'로 바꾸는 요청을 생성합니다.
+ 대상 객체의 ETag가 '*e5f3g7h8i9j0*'과 일치하지 않는 경우에만 이름 바꾸기가 발생하도록 하는 `.destinationIfNoneMatch(noneMatchETag)`를 사용하는 조건을 포함합니다.

새 이름이 지정되어 있고 ETag가 지정된 객체가 이미 있는 경우 `412 Precondition Failed` 오류와 함께 작업이 실패합니다.

------
#### [ SDK for Python ]

SDK for Python을 사용하여 객체의 이름을 바꿀 수 있습니다. 이러한 예시를 사용하려면 *사용자 입력 자리 표시자*를 실제 정보로 대체하세요.

다음 예시에서는 AWS SDK for Python(Boto3)을 사용하여 객체의 이름을 바꾸는 방법을 보여줍니다.

```
def basic_rename(bucket, source_key, destination_key):
    try:
        s3.rename_object(
            Bucket=amzn-s3-demo-bucket--usw2-az1--x-s3,
            Key=destination_key,
            RenameSource=f"{source_key}"
        )
        print(f"Successfully renamed {source_key} to {destination_key}")
    except ClientError as e:
        print(f"Error renaming object: {e}")
```

이 코드는 다음을 수행합니다.
+ *amzn-s3-demo-bucket--usw2-az1--x-s3* 디렉터리 버킷에서 객체 이름을 *source\$1key*에서 *destination\$1key*로 바꿉니다.
+ 객체 이름 바꾸기에 성공하면 성공 메시지를 인쇄하고 실패하면 오류 메시지를 인쇄합니다.

다음 예시에서는 AWS SDK for Python(Boto3)을 사용하여 `SourceIfMatch` 및 `DestinationIfNoneMatch` 조건을 사용해 객체의 이름을 바꾸는 방법을 보여줍니다.

```
def rename_with_conditions(bucket, source_key, destination_key, source_etag, dest_etag):
    try:
        s3.rename_object(
            Bucket=amzn-s3-demo-bucket--usw2-az1--x-s3,
            Key=destination_key,
            RenameSource=f"{amzn-s3-demo-bucket--usw2-az1--x-s3}/{source_key}",
            SourceIfMatch=source_ETag,
            DestinationIfNoneMatch=dest_ETag
        )
        print(f"Successfully renamed {source_key} to {destination_key} with conditions")
    except ClientError as e:
        print(f"Error renaming object: {e}")
```

이 코드는 다음을 수행합니다.
+ 조건부 이름 바꾸기 작업을 수행하고 `SourceIfMatch` 및 `DestinationIfNoneMatch`라는 두 가지 조건을 적용합니다. 이러한 조건을 조합하면 객체가 수정되지 않고 객체가 지정된 새 이름으로 아직 존재하지 않게 됩니다.
+ *amzn-s3-demo-bucket--usw2-az1--x-s3* 디렉터리 버킷에서 객체 이름을 *source\$1key*에서 *destination\$1key*로 바꿉니다.
+ 객체 이름 바꾸기에 성공하면 성공 메시지를 인쇄하고 실패하거나 조건이 충족되지 않으면 오류 메시지를 인쇄합니다.

------
#### [ SDK for Rust ]

SDK for Rust를 사용하여 객체의 이름을 바꿀 수 있습니다. 이러한 예시를 사용하려면 *사용자 입력 자리 표시자*를 실제 정보로 대체하세요.

다음 예시에서는 SDK for Rust를 사용하여 *amzn-s3-demo-bucket--usw2-az1--x-s3* 디렉터리 버킷의 객체 이름을 바꾸는 방법을 보여줍니다.

```
async fn basic_rename_example(client: &Client) -> Result<(), Box<dyn Error>> {
    let response = client
        .rename_object()
        .bucket(" amzn-s3-demo-bucket--usw2-az1--x-s3")
        .key("new-name.txt")  // New name/path for the object
        .rename_source("old-name.txt")  // Original object name/path
        .send()
        .await?;
    Ok(())
}
```

이 코드는 다음을 수행합니다.
+ *amzn-s3-demo-bucket--usw2-az1--x-s3* 디렉터리 버킷에서 객체 이름을 '*old-name.tx*'에서 '*new-name.txt*'로 바꾸는 요청을 생성합니다.
+ 잠재적 오류를 처리할 `Result` 유형을 반환합니다.

------

### REST API 사용
<a name="directory-bucket-rename-api"></a>

 객체 이름을 바꾸기 위해 REST 요청을 보낼 수 있습니다. 자세한 내용은 **Amazon S3 API 참조의 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_RenameObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_RenameObject.html) 섹션을 참조하세요.

### Mountpoint for Amazon S3 사용
<a name="directory-bucket-rename-api"></a>

 1.19.0 버전부터 Mountpoint for Amazon S3는 S3 Express One Zone에서 객체 이름 바꾸기를 지원합니다. Mountpoint에 대한 자세한 내용은 [Mountpoint 작업](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mountpoint.html)을 참조하세요.

# 디렉터리 버킷에 객체 업로드
<a name="directory-buckets-objects-upload"></a>

Amazon S3 디렉터리 버킷을 생성하면 여기에 객체를 업로드할 수 있습니다. 다음 예제에서는 S3 콘솔 및 AWS SDK를 사용하여 객체를 디렉터리 버킷에 업로드하는 방법을 보여줍니다. S3 Express One Zone을 사용한 대량 객체 작업에 대한 자세한 내용은 [객체 관리](directory-bucket-high-performance.md#s3-express-features-object-management) 섹션을 참조하세요.

## S3 콘솔 사용
<a name="directory-bucket-upload-console"></a>

1. AWS Management Console에 로그인한 후 [https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/)에서 Amazon S3 콘솔을 엽니다.

1. 왼쪽 탐색 창에서 **디렉터리 버킷**을 선택합니다.

1. 파일 및 폴더를 업로드하려는 버킷의 이름을 선택합니다.

1. **객체** 탭에서 **업로드**를 선택합니다.

1. **업로드** 페이지에서 다음 중 하나를 수행합니다.
   + 파일 및 폴더를 점선으로 표시된 업로드 영역으로 끌어다 놓습니다.
   + **파일 추가** 또는 **폴더 추가**를 선택하고 업로드할 파일 또는 폴더를 선택한 후 **열기** 또는 **업로드**를 선택합니다.

1. **체크섬**에서 사용하려는 **체크섬 함수**를 선택합니다.

   (선택 사항) 크기가 16MB 미만인 단일 객체를 업로드하는 경우 미리 계산된 체크섬 값을 지정할 수도 있습니다. 미리 계산된 값을 제공하면 Amazon S3는 선택한 체크섬 함수를 사용하여 계산한 값과 비교합니다. 값이 일치하지 않으면 업로드가 시작되지 않습니다.

1. **권한** 및 **속성** 섹션의 옵션은 자동으로 기본 설정으로 설정되며 수정할 수 없습니다. 퍼블릭 액세스 차단은 자동으로 활성화되며 디렉터리 버킷에 대해서는 S3 버전 관리 및 S3 객체 잠금을 활성화할 수 없습니다.

   (선택 사항) 키-값 쌍의 메타데이터를 객체에 추가하려면 **속성** 섹션을 확장한 다음 **메타데이터** 섹션에서 **메타데이터 추가**를 선택합니다.

1. 나열된 파일을 업로드하려면 **업로드**를 선택합니다.

   Amazon S3가 객체와 폴더를 업로드합니다. 업로드가 완료되면 **업로드: 상태** 페이지에서 성공 메시지를 볼 수 있습니다.

## AWS SDK 사용
<a name="directory-bucket-upload-sdks"></a>

------
#### [ SDK for Java 2.x ]

**Example**  

```
public static void putObject(S3Client s3Client, String bucketName, String objectKey, Path filePath) {
       //Using File Path to avoid loading the whole file into memory
       try {
           PutObjectRequest putObj = PutObjectRequest.builder()
                   .bucket(bucketName)
                   .key(objectKey)
                   //.metadata(metadata)
                   .build();
           s3Client.putObject(putObj, filePath);               
           System.out.println("Successfully placed " + objectKey +" into bucket "+bucketName);
                                              
       }
       
       catch (S3Exception e) {
           System.err.println(e.getMessage());
           System.exit(1);
       }
}
```

------
#### [ SDK for Python ]

**Example**  

```
import boto3
import botocore
from botocore.exceptions import ClientError
    
    
def put_object(s3_client, bucket_name, key_name, object_bytes):
    """  
    Upload data to a directory bucket.
    :param s3_client: The boto3 S3 client
    :param bucket_name: The bucket that will contain the object
    :param key_name: The key of the object to be uploaded
    :param object_bytes: The data to upload
    """
    try:
        response = s3_client.put_object(Bucket=bucket_name, Key=key_name,
                             Body=object_bytes)
        print(f"Upload object '{key_name}' to bucket '{bucket_name}'.") 
        return response
    except ClientError:    
        print(f"Couldn't upload object '{key_name}' to bucket '{bucket_name}'.")
        raise

def main():
    # Share the client session with functions and objects to benefit from S3 Express One Zone auth key
    s3_client = boto3.client('s3')
    # Directory bucket name must end with --zone-id--x-s3
    resp = put_object(s3_client, 'doc-bucket-example--use1-az5--x-s3', 'sample.txt', b'Hello, World!')
    print(resp)

if __name__ == "__main__":
    main()
```

------

## AWS CLI 사용
<a name="directory-upload-object-cli"></a>

다음 `put-object` 예시 명령은 AWS CLI를 사용하여 Amazon S3의 객체를 업로드하는 방법을 보여 줍니다. 이 명령을 실행하려면 `user input placeholders`를 사용자의 정보로 대체합니다.

```
aws s3api put-object --bucket bucket-base-name--zone-id--x-s3 --key sampleinut/file001.bin --body bucket-seed/file001.bin
```

자세한 내용은 *AWS CLI 명령 참조*의 [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/put-object.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/put-object.html) 섹션을 참조하십시오.

**Topics**
+ [디렉터리 버킷에 멀티파트 업로드 사용](s3-express-using-multipart-upload.md)

# 디렉터리 버킷에 멀티파트 업로드 사용
<a name="s3-express-using-multipart-upload"></a>

멀티파트 업로드 프로세스를 사용하면 단일 객체를 여러 부분의 집합으로 업로드할 수 있습니다. 각 부분은 객체 데이터의 연속적인 부분입니다. 이러한 객체 부분은 독립적으로 그리고 임의의 순서로 업로드할 수 있습니다. 부분의 전송이 실패할 경우 다른 부분에 영향을 주지 않고도 해당 부분을 재전송할 수 있습니다. 객체의 모든 부분이 업로드되면 Amazon S3가 이들 부분을 수집하여 객체를 생성합니다. 일반적으로 객체 크기가 100MB에 근접할 경우, 단일 작업에서 객체를 업로드하는 대신 멀티파트 업로드 사용을 고려해 봐야 합니다.

멀티파트 업로드 사용은 다음 이점을 제공합니다.
+ **개선된 처리량 개선** - 부분을 병렬적으로 업로드하여 처리량을 개선할 수 있습니다.
+ **네트워크 문제로부터 빠른 복구** - 더 작아진 부분 크기는 네트워크 오류로 인해 실패한 업로드 재시작의 영향을 최소화합니다.
+ **객체 업로드 일시 중지 및 재개** – 객체 부분을 장시간에 걸쳐 업로드할 수 있습니다. 멀티파트 업로드가 시작되면 만료 날짜가 없습니다. 멀티파트 업로드를 명시적으로 완료하거나 중단해야 합니다.
+ **최종 객체 크기를 알기 전에 업로드를 시작** – 객체를 생성하는 동안 업로드할 수 있습니다.

다음 방법으로 멀티파트 업로드를 사용하는 것이 좋습니다.
+ 안정적인 높은 대역폭 네트워크를 통해 큰 객체를 업로드하는 경우, 멀티파트 업로드를 사용하여 멀티 스레드 성능을 위해 여러 객체 부분을 동시에 업로드함으로써 대역폭 사용을 극대화합니다.
+ 불규칙한 네트워크를 통해 업로드하는 경우, 멀티파트 업로드를 사용하여 업로드가 다시 시작되는 것을 방지하여 네트워크 오류에 대한 복원력을 높입니다. 멀티파트 업로드를 사용하는 경우, 업로드 중에 중단된 부분만 다시 업로드해야 합니다. 객체 업로드를 처음부터 다시 시작하지 않아도 됩니다.

멀티파트 업로드를 사용하여 디렉터리 버킷의 Amazon S3 Express One Zone 스토리지 클래스에 객체를 업로드하는 경우, 멀티파트 업로드 프로세스는 멀티파트 업로드를 사용하여 범용 버킷에 객체를 업로드하는 프로세스와 유사합니다. 하지만 몇 가지 큰 차이가 있습니다.

멀티파트 업로드를 사용하여 S3 Express One Zone에 객체를 업로드하는 방법에 대한 자세한 정보는 다음 주제를 참조하세요.

**Topics**
+ [멀티파트 업로드 프로세스](#s3-express-mpu-process)
+ [멀티파트 업로드 작업을 사용한 체크섬](#s3-express-mpuchecksums)
+ [동시 멀티파트 업로드 작업](#s3-express-distributedmpupload)
+ [멀티파트 업로드 및 요금](#s3-express-mpuploadpricing)
+ [멀티파트 업로드 API 작업 및 권한](#s3-express-mpuAndPermissions)
+ [예제](#directory-buckets-multipart-upload-examples)

## 멀티파트 업로드 프로세스
<a name="s3-express-mpu-process"></a>

멀티파트 업로드는 다음과 같은 3단계 프로세스입니다.
+ 업로드를 시작합니다.
+ 객체 부분을 업로드합니다.
+ 부분을 모두 업로드한 후 멀티파트 업로드를 완료합니다.



Amazon S3에 멀티파트 업로드 완료 요청이 전송되면 버킷의 다른 객체와 같이 이 객체에 액세스할 수 있도록 업로드된 각 부분을 모아 완전한 객체를 구성합니다.

**멀티파트 업로드 시작**  
멀티파트 업로드 시작 요청을 전송하면 Amazon S3는 멀티파트 업로드에 대한 고유 식별자인 업로드 ID와 함께 응답을 반환합니다. 파트 업로드, 부분 목록 확인, 업로드 완료 또는 업로드 중단 요청 시 항상 이 업로드 ID를 포함해야 합니다.

**부분 업로드**  
부분을 업로드할 때 업로드 ID와 함께 부분 번호를 지정해야 합니다. S3 Express One Zone에서 멀티파트 업로드를 사용하는 경우 멀티파트의 부분 번호는 연속된 번호여야 합니다. 연속되지 않는 부분 번호로 멀티파트 업로드 요청을 완료하려고 하면 `HTTP 400 Bad Request`(유효하지 않은 부분 순서) 오류가 생성됩니다.

부분 번호를 사용하여 업로드하는 객체에서 각 부분과 그 위치를 고유하게 식별합니다. 이전에 업로드한 부분과 동일한 부분 번호로 새 부분을 업로드할 경우 이전에 업로드한 부분을 덮어쓰게 됩니다.

부분을 업로드할 때마다 Amazon S3는 그 응답으로 엔터티 태그(ETag) 헤더를 반환합니다. 각 부분 업로드에 대해 부분 번호와 ETag 값을 기록해야 합니다. 모든 객체 파트 업로드의 ETag 값은 동일하게 유지되지만 각 파트에는 다른 파트 번호가 할당됩니다. 이후 멀티파트 업로드를 완료하기 위한 요청에 이러한 값을 포함해야 하기 때문입니다.

Amazon S3는 S3 버킷에 업로드되는 모든 새 객체를 자동으로 암호화합니다. 멀티파트 업로드를 수행할 때 요청에서 암호화 정보를 지정하지 않은 경우 업로드된 파트의 암호화 설정이 대상 버킷의 기본 암호화 구성으로 설정됩니다. Amazon S3 버킷의 기본 암호화 구성은 항상 활성화되어 있으며, 최소한 Amazon S3 관리형 키를 통한 서버 측 암호화(SSE-S3)로 설정되어 있습니다. 디렉터리 버킷의 경우 SSE-S3 및 AWS KMS 키를 통한 서버 측 암호화(SSE-KMS)가 지원됩니다. 자세한 내용은 [데이터 보호 및 암호화](s3-express-data-protection.md) 섹션을 참조하세요.

**멀티파트 업로드 완료**  
멀티파트 업로드를 완료하면 Amazon S3는 부분 번호를 바탕으로 오름차순으로 각 부분을 결합하여 객체를 완성합니다. 성공적으로 *완료* 요청이 수행되면 부분은 더 이상 존재하지 않습니다.

**멀티파트 업로드 완료 요청에는 업로드 ID와 각 부분 번호 및 해당 ETag 값의 목록이 포함되어야 합니다. Amazon S3 응답에는 결합된 객체 데이터를 고유하게 식별하는 ETag가 포함됩니다. 이 ETag는 객체 데이터의 MD5 해시가 아닙니다.

**멀티파트 업로드 나열**  
특정 멀티파트 업로드 또는 진행 중인 모든 멀티파트 업로드에 대해 부분 목록을 확인할 수 있습니다. 부분 목록 조회 작업은 특정 멀티파트 업로드에 대해 업로드한 부분의 정보를 반환합니다. 각 부분 목록 조회 요청에 대해 Amazon S3는 특정 멀티파트 업로드에서 최대 1,000개의 부분에 대해 부분 정보를 반환합니다. 멀티파트 업로드에서 파트가 1,000개 이상일 경우 모든 파트를 검색하려면 페이지 매김을 사용해야 합니다.

반환된 부분 목록에는 업로드가 완료되지 않은 부분이 포함되지 않습니다. *멀티파트 업로드 나열* 작업을 사용하여 진행 중인 멀티파트 업로드의 목록을 확인할 수 있습니다.

진행 중인 멀티파트 업로드는 시작했지만 아직 완료 또는 중단하지 않은 업로드입니다. 각 요청은 최대 1,000개의 멀티파트 업로드를 반환합니다. 진행 중인 멀티파트 업로드가 1,000개 이상일 경우 남은 멀티파트 업로드를 모두 검색하려면 추가 요청을 전송해야 합니다. 반환된 목록은 확인을 위해서만 사용합니다. *멀티파트 업로드 완료* 요청을 전송할 때 이 나열 결과를 사용하면 안 됩니다. 그 대신, 부분을 업로드할 때 지정한 부분 번호 및 Amazon S3가 반환한 해당 ETag 값의 목록을 보관해야 합니다.

멀티파트 업로드 목록에 대한 자세한 내용은 **Amazon Simple Storage Service API 참조의 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html)를 참조하세요.

## 멀티파트 업로드 작업을 사용한 체크섬
<a name="s3-express-mpuchecksums"></a>

객체를 업로드할 때 객체 무결성을 검사하기 위해 체크섬 알고리즘을 지정할 수 있습니다. 디렉터리 버킷에는 MD5가 지원되지 않습니다. 다음 SHA(보안 해시 알고리즘) 또는 CRC(순환 중복 검사) 데이터 무결성 확인 알고리즘 중 하나를 지정할 수 있습니다.
+ CRC32 
+ CRC32C 
+ SHA-1
+ SHA-256

Amazon S3 REST API 또는 AWS를 사용하여 `GetObject` 또는 `HeadObject`를 통해 개별 부분의 체크섬 값을 검색할 수 있습니다. 아직 진행 중인 멀티파트 업로드의 개별 부분에 대한 체크섬 값을 검색하려면 `ListParts`를 사용하면 됩니다.

**중요**  
이전의 체크섬 알고리즘을 사용하는 경우 멀티파트 번호에 연속된 파트 번호를 사용해야 합니다. 연속되지 않는 부분 번호로 멀티파트 업로드 요청을 완료하려고 하면 Amazon S3에서 `HTTP 400 Bad Request`(유효하지 않은 부분 순서) 오류가 생성됩니다.

 멀티파트 업로드 객체를 통한 체크섬 작업에 대한 자세한 내용은 [Amazon S3에서 객체 무결성 확인](checking-object-integrity.md) 섹션을 참조하세요.

## 동시 멀티파트 업로드 작업
<a name="s3-express-distributedmpupload"></a>

분산 개발 환경에서는 애플리케이션에서 한 객체에 대해 동시에 여러 업데이트를 시작할 수 있습니다. 예를 들어 애플리케이션은 동일한 객체 키를 사용하여 여러 멀티파트 업로드를 시작할 수 있습니다. 이러한 각 업로드에 대해 애플리케이션은 부분을 업로드한 후 Amazon S3가 객체를 생성하도록 업로드 완료 요청을 전송할 수 있습니다. S3 Express One Zone의 경우 객체 생성 시간은 멀티파트 업로드 완료 날짜입니다.

**중요**  
디렉터리 버킷에 저장된 객체에는 버전 관리가 지원되지 않습니다.

## 멀티파트 업로드 및 요금
<a name="s3-express-mpuploadpricing"></a>

멀티파트 업로드가 시작되면 Amazon S3는 업로드가 완료되거나 중단될 때까지 모든 파트를 계속 유지합니다. 수명 주기가 끝날 때까지 이 멀티파트 업로드와 관련 부분의 모든 스토리지, 대역폭 및 요청에 대해 비용이 청구됩니다. 멀티파트 업로드를 중단하면 Amazon S3가 업로드 결과 및 업로드된 모든 파트를 삭제하므로 더 이상 비용이 청구되지 않습니다. 지정한 스토리지 클래스에 관계없이 불완전한 멀티파트 업로드를 삭제하는 경우 조기 삭제 요금이 부과되지 않습니다. 요금에 대한 자세한 내용은 [Amazon S3 요금](https://aws.amazon.com/s3/pricing/)을 참조하세요.

**중요**  
전체 멀티파트 업로드 요청이 성공적으로 전송되지 않으면 객체 파트가 어셈블되지 않고 객체가 생성되지 않습니다. 업로드된 부분에 연결된 모든 스토리지에 대해 요금이 청구됩니다. 멀티파트 업로드를 완료하여 객체를 생성하거나 멀티파트 업로드를 중지하여 업로드된 파트를 제거하는 것이 중요합니다.  
디렉터리 버킷을 삭제하기 전에 진행 중인 모든 멀티파트 업로드를 완료하거나 중단해야 합니다. 디렉터리 버킷은 S3 수명 주기 구성을 지원하지 않습니다. 필요한 경우 활성 멀티파트 업로드를 나열한 다음 업로드를 중단한 후 버킷을 삭제할 수 있습니다.

## 멀티파트 업로드 API 작업 및 권한
<a name="s3-express-mpuAndPermissions"></a>

디렉터리 버킷의 객체 관리 API 작업에 대한 액세스를 허용하려면 버킷 정책 또는 AWS Identity and Access Management(IAM) ID 기반 정책에서 디렉터리 버킷에 `s3express:CreateSession` 권한을 부여합니다.

멀티파트 업로드 작업을 수행하려면 필수 권한이 있어야 합니다. 버킷 정책 또는 IAM ID 기반 정책을 사용하여 IAM 보안 주체에 이러한 작업을 수행할 권한을 부여할 수 있습니다. 다음 테이블에는 여러 멀티파트 업로드 작업에 대한 필수 권한이 나와 있습니다.

`Initiator` 요소를 통해 멀티파트 업로드의 이니시에이터를 식별할 수 있습니다. 이니시에이터가 AWS 계정일 경우 이 요소는 `Owner` 요소와 동일한 정보를 제공합니다. 시작한 사용자가 IAM 사용자일 경우 이 요소는 사용자 ARN 및 표시 이름을 제공합니다.


| 작업 | 필수 권한 | 
| --- | --- | 
|  멀티파트 업로드 생성  |  멀티파트 업로드를 생성하려면 디렉터리 버킷에 대해 `s3express:CreateSession` 작업을 수행할 수 있어야 합니다.  | 
|  멀티파트 업로드 시작  |  멀티파트 업로드를 시작하려면 디렉터리 버킷에 대해 `s3express:CreateSession` 작업을 수행할 수 있어야 합니다.  | 
| 부분 업로드 |  부분을 업로드하려면 디렉터리 버킷에 대해 `s3express:CreateSession` 작업을 수행할 수 있어야 합니다. 이니시에이터가 부분을 업로드하려면 버킷 소유자는 이니시에이터가 디렉터리 버킷에 대한 `s3express:CreateSession` 작업을 수행하도록 허용해야 합니다.  | 
| 부분 업로드(복사) |  부분을 업로드하려면 디렉터리 버킷에 대해 `s3express:CreateSession` 작업을 수행할 수 있어야 합니다. 버킷 소유자는 객체의 멀티파트 업로드를 시작하는 사용자에게 `s3express:CreateSession` 작업을 수행할 수 있는 권한을 부여해야 합니다.  | 
| 멀티파트 업로드 완료 |  멀티파트 업로드를 완료하려면 디렉터리 버킷에 대해 `s3express:CreateSession` 작업을 수행할 수 있어야 합니다. 버킷 소유자는 이니시에이터가 멀티파트 업로드를 완료할 수 있도록 객체에 대해 `s3express:CreateSession` 작업을 수행할 수 있는 권한을 부여해야 합니다.  | 
| 멀티파트 업로드 중단 |  멀티파트 업로드를 중단하려면 객체에 대해 `s3express:CreateSession` 작업을 수행할 수 있어야 합니다. 멀티파트 업로드를 중단하려면 이니시에이터에게 `s3express:CreateSession` 작업을 수행할 수 있는 명시적 허용 액세스 권한을 부여해야 합니다.  | 
| 부분 나열 |  멀티파트 업로드의 부분을 나열하려면 디렉터리 버킷에 대해 `s3express:CreateSession` 작업을 수행할 수 있어야 합니다.  | 
| 진행 중인 멀티파트 업로드 나열 |  버킷에 대해 진행 중인 멀티파트 업로드를 나열하려면 버킷에 대해 `s3:ListBucketMultipartUploads` 작업을 수행할 수 있어야 합니다.  | 

### 멀티파트 업로드를 위한 API 작업 지원
<a name="s3-express-mpu-apis"></a>

Amazon Simple Storage Service API 참조의 다음 섹션에서는 멀티파트 업로드를 위한 Amazon S3 REST API 작업에 대해 설명합니다.
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html)

## 예제
<a name="directory-buckets-multipart-upload-examples"></a>

멀티파트 업로드를 사용하여 디렉터리 버킷의 S3 Express One Zone에 객체를 업로드하려면 다음 예제를 참조하세요.

**Topics**
+ [멀티파트 업로드 생성](#directory-buckets-multipart-upload-examples-create)
+ [멀티파트 업로드의 부분 업로드](#directory-buckets-multipart-upload-examples-upload-part)
+ [멀티파트 업로드 완료](#directory-buckets-multipart-upload-examples-complete)
+ [멀티파트 업로드 중단](#directory-buckets-multipart-upload-examples-abort)
+ [멀티파트 업로드 복사 작업 생성](#directory-buckets-multipart-upload-examples-upload-part-copy)
+ [진행 중인 멀티파트 업로드 나열](#directory-buckets-multipart-upload-examples-list)
+ [멀티파트 업로드의 부분 나열](#directory-buckets-multipart-upload-examples-list-parts)

### 멀티파트 업로드 생성
<a name="directory-buckets-multipart-upload-examples-create"></a>

**참고**  
디렉터리 버킷의 경우 `CreateMultipartUpload` 작업 및 `UploadPartCopy` 작업을 수행할 때 버킷의 기본 암호화는 원하는 암호화 구성을 사용해야 하며, `CreateMultipartUpload` 요청에 제공하는 요청 헤더는 대상 버킷의 기본 암호화 구성과 일치해야 합니다.

다음 예시는 멀티파트 업로드를 만드는 방법을 보여 줍니다.

#### AWS SDK 사용
<a name="directory-buckets-multipart-upload-create-sdks"></a>

------
#### [ SDK for Java 2.x ]

**Example**  

```
/**
 * This method creates a multipart upload request that generates a unique upload ID that is used to track
 * all the upload parts
 *
 * @param s3
 * @param bucketName - for example, 'doc-example-bucket--use1-az4--x-s3'
 * @param key
 * @return
 */
 private static String createMultipartUpload(S3Client s3, String bucketName, String key) {
 
     CreateMultipartUploadRequest createMultipartUploadRequest = CreateMultipartUploadRequest.builder() 
             .bucket(bucketName)
             .key(key)
             .build();
             
     String uploadId = null;
     
     try {
         CreateMultipartUploadResponse response = s3.createMultipartUpload(createMultipartUploadRequest);
         uploadId = response.uploadId();
     }
     catch (S3Exception e) {
         System.err.println(e.awsErrorDetails().errorMessage());
         System.exit(1);
     }
     return uploadId;
```

------
#### [ SDK for Python ]

**Example**  

```
def create_multipart_upload(s3_client, bucket_name, key_name):
    '''
   Create a multipart upload to a directory bucket
   
   :param s3_client: boto3 S3 client
   :param bucket_name: The destination bucket for the multipart upload
   :param key_name: The key name for the object to be uploaded
   :return: The UploadId for the multipart upload if created successfully, else None
   '''
   
   try:
        mpu = s3_client.create_multipart_upload(Bucket = bucket_name, Key = key_name)
        return mpu['UploadId'] 
    except ClientError as e:
        logging.error(e)
        return None
```

------

#### AWS CLI 사용
<a name="directory-bucket-multipart-upload-create-cli"></a>

이 예시는 AWS CLI를 사용하여 디렉터리 버킷에 대한 멀티파트 업로드를 생성하는 방법을 보여 줍니다. 이 명령은 *KEY\$1NAME* 객체에 대해 *bucket-base-name*--*zone-id*--x-s3 디렉터리 버킷에 멀티파트 업로드를 시작합니다. 명령을 사용하려면 *사용자 입력 자리 표시자*를 사용자의 정보로 대체합니다.

```
aws s3api create-multipart-upload --bucket bucket-base-name--zone-id--x-s3 --key KEY_NAME
```

자세한 내용은 AWS Command Line Interface의 [create-multipart-upload](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/create-multipart-upload.html)를 참조하세요.

### 멀티파트 업로드의 부분 업로드
<a name="directory-buckets-multipart-upload-examples-upload-part"></a>

다음 코드 예시는 멀티파트 업로드의 일부를 업로드하는 방법을 보여 줍니다.

#### AWS SDK 사용
<a name="directory-buckets-multipart-upload-part-sdks"></a>

------
#### [ SDK for Java 2.x ]

다음 예시는 SDK for Java 2.x를 사용하여 단일 객체를 여러 부분으로 나눈 다음 디렉터리 버킷에 업로드하는 방법을 보여 줍니다.

**Example**  

```
/**
 * This method creates part requests and uploads individual parts to S3 and then returns all the completed parts
 *
 * @param s3
 * @param bucketName
 * @param key
 * @param uploadId
 * @throws IOException
 */
 private static ListCompletedPartmultipartUpload(S3Client s3, String bucketName, String key, String uploadId, String filePath) throws IOException {

        int partNumber = 1;
        ListCompletedPart completedParts = new ArrayList<>();
        ByteBuffer bb = ByteBuffer.allocate(1024 * 1024 * 5); // 5 MB byte buffer

        // read the local file, breakdown into chunks and process
        try (RandomAccessFile file = new RandomAccessFile(filePath, "r")) {
            long fileSize = file.length();
            int position = 0;
            while (position < fileSize) {
                file.seek(position);
                int read = file.getChannel().read(bb);

                bb.flip(); // Swap position and limit before reading from the buffer.
                UploadPartRequest uploadPartRequest = UploadPartRequest.builder()
                        .bucket(bucketName)
                        .key(key)
                        .uploadId(uploadId)
                        .partNumber(partNumber)
                        .build();

                UploadPartResponse partResponse = s3.uploadPart(
                        uploadPartRequest,
                        RequestBody.fromByteBuffer(bb));

                CompletedPart part = CompletedPart.builder()
                        .partNumber(partNumber)
                        .eTag(partResponse.eTag())
                        .build();
                completedParts.add(part);

                bb.clear();
                position += read;
                partNumber++;
            }
        } 
        
        catch (IOException e) {
            throw e;
        }
        return completedParts;
    }
```

------
#### [ SDK for Python ]

다음 예시는 SDK for Python을 사용하여 단일 객체를 여러 부분으로 나눈 다음 디렉터리 버킷에 업로드하는 방법을 보여 줍니다.

**Example**  

```
def multipart_upload(s3_client, bucket_name, key_name, mpu_id, part_size):
    '''
    Break up a file into multiple parts and upload those parts to a directory bucket

    :param s3_client: boto3 S3 client
    :param bucket_name: Destination bucket for the multipart upload
    :param key_name: Key name for object to be uploaded and for the local file that's being uploaded
    :param mpu_id: The UploadId returned from the create_multipart_upload call
    :param part_size: The size parts that the object will be broken into, in bytes. 
                      Minimum 5 MiB, Maximum 5 GiB. There is no minimum size for the last part of your multipart upload.
    :return: part_list for the multipart upload if all parts are uploaded successfully, else None
    '''
    
    part_list = []
    try:
        with open(key_name, 'rb') as file:
            part_counter = 1
            while True:
                file_part = file.read(part_size)
                if not len(file_part):
                    break
                upload_part = s3_client.upload_part(
                    Bucket = bucket_name,
                    Key = key_name,
                    UploadId = mpu_id,
                    Body = file_part,
                    PartNumber = part_counter
                )
                part_list.append({'PartNumber': part_counter, 'ETag': upload_part['ETag']})
                part_counter += 1
    except ClientError as e:
        logging.error(e)
        return None
    return part_list
```

------

#### AWS CLI 사용
<a name="directory-bucket-multipart-upload-part-cli"></a>

이 예시는 AWS CLI를 사용하여 단일 객체를 여러 부분으로 나눈 다음 디렉터리 버킷에 업로드하는 방법을 보여 줍니다. 명령을 사용하려면 *사용자 입력 자리 표시자*를 사용자의 정보로 대체합니다.

```
aws s3api upload-part --bucket bucket-base-name--zone-id--x-s3 --key KEY_NAME --part-number 1 --body LOCAL_FILE_NAME --upload-id "AS_mgt9RaQE9GEaifATue15dAAAAAAAAAAEMAAAAAAAAADQwNzI4MDU0MjUyMBYAAAAAAAAAAA0AAAAAAAAAAAH2AfYAAAAAAAAEBSD0WBKMAQAAAABneY9yBVsK89iFkvWdQhRCcXohE8RbYtc9QvBOG8tNpA"
```

자세한 내용은 AWS Command Line Interface의 [upload-part](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/upload-part.html)를 참조하세요.

### 멀티파트 업로드 완료
<a name="directory-buckets-multipart-upload-examples-complete"></a>

다음 예시는 멀티파트 업로드를 완료하는 방법을 보여 줍니다.

#### AWS SDK 사용
<a name="directory-buckets-multipart-upload-complete-sdks"></a>

------
#### [ SDK for Java 2.x ]

다음 예시는 SDK for Java 2.x를 사용하여 멀티파트 업로드를 완료하는 방법을 보여 줍니다.

**Example**  

```
/**
 * This method completes the multipart upload request by collating all the upload parts
 * @param s3
 * @param bucketName - for example, 'doc-example-bucket--usw2-az1--x-s3'
 * @param key
 * @param uploadId
 * @param uploadParts
 */
 private static void completeMultipartUpload(S3Client s3, String bucketName, String key, String uploadId, ListCompletedPart uploadParts) {
        CompletedMultipartUpload completedMultipartUpload = CompletedMultipartUpload.builder()
                .parts(uploadParts)
                .build();

        CompleteMultipartUploadRequest completeMultipartUploadRequest =
                CompleteMultipartUploadRequest.builder()
                        .bucket(bucketName)
                        .key(key)
                        .uploadId(uploadId)
                        .multipartUpload(completedMultipartUpload)
                        .build();

        s3.completeMultipartUpload(completeMultipartUploadRequest);
    }

    public static void multipartUploadTest(S3Client s3, String bucketName, String key, String localFilePath)  {
        System.out.println("Starting multipart upload for: " + key);
        try {
            String uploadId = createMultipartUpload(s3, bucketName, key);
            System.out.println(uploadId);
            ListCompletedPart parts = multipartUpload(s3, bucketName, key, uploadId, localFilePath);
            completeMultipartUpload(s3, bucketName, key, uploadId, parts);
            System.out.println("Multipart upload completed for: " + key);
        } 
        
        catch (Exception e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }
```

------
#### [ SDK for Python ]

다음 예시는 SDK for Python을 사용하여 멀티파트 업로드를 완료하는 방법을 보여 줍니다.

**Example**  

```
def complete_multipart_upload(s3_client, bucket_name, key_name, mpu_id, part_list):
    '''
    Completes a multipart upload to a directory bucket

    :param s3_client: boto3 S3 client
    :param bucket_name: The destination bucket for the multipart upload
    :param key_name: The key name for the object to be uploaded
    :param mpu_id: The UploadId returned from the create_multipart_upload call
    :param part_list: The list of uploaded part numbers with their associated ETags 
    :return: True if the multipart upload was completed successfully, else False
    '''
    
    try:
        s3_client.complete_multipart_upload(
            Bucket = bucket_name,
            Key = key_name,
            UploadId = mpu_id,
            MultipartUpload = {
                'Parts': part_list
            }
        )
    except ClientError as e:
        logging.error(e)
        return False
    return True
    
if __name__ == '__main__':
    MB = 1024 ** 2
    region = 'us-west-2'
    bucket_name = 'BUCKET_NAME'
    key_name = 'OBJECT_NAME'
    part_size = 10 * MB
    s3_client = boto3.client('s3', region_name = region)
    mpu_id = create_multipart_upload(s3_client, bucket_name, key_name)
    if mpu_id is not None:
        part_list = multipart_upload(s3_client, bucket_name, key_name, mpu_id, part_size)
        if part_list is not None:
            if complete_multipart_upload(s3_client, bucket_name, key_name, mpu_id, part_list):
                print (f'{key_name} successfully uploaded through a ultipart upload to {bucket_name}')
            else:
                print (f'Could not upload {key_name} hrough a multipart upload to {bucket_name}')
```

------

#### AWS CLI 사용
<a name="directory-bucket-multipart-upload-complete-cli"></a>

이 예시는 AWS CLI을 사용하여 디렉터리 버킷에 대한 멀티파트 업로드를 완료하는 방법을 보여 줍니다. 명령을 사용하려면 *사용자 입력 자리 표시자*를 사용자의 정보로 대체합니다.

```
aws s3api complete-multipart-upload --bucket bucket-base-name--zone-id--x-s3 --key KEY_NAME --upload-id "AS_mgt9RaQE9GEaifATue15dAAAAAAAAAAEMAAAAAAAAADQwNzI4MDU0MjUyMBYAAAAAAAAAAA0AAAAAAAAAAAH2AfYAAAAAAAAEBSD0WBKMAQAAAABneY9yBVsK89iFkvWdQhRCcXohE8RbYtc9QvBOG8tNpA" --multipart-upload file://parts.json
```

이 예시는 전체 파일로 리어셈블해야 하는 멀티파트 업로드의 부분을 설명하는 JSON 구조를 사용합니다. 이 예시에서는 `file://` 접두사를 사용하여 `parts`라는 로컬 폴더에 있는 파일에서 JSON 구조를 로드합니다.

parts.json:

```
parts.json
{
  "Parts": [
    {
      "ETag": "6b78c4a64dd641a58dac8d9258b88147",
      "PartNumber": 1
    }
  ]
}
```

자세한 내용은 AWS Command Line Interface의 [complete-multipart-upload](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/complete-multipart-upload.html)를 참조하세요.

### 멀티파트 업로드 중단
<a name="directory-buckets-multipart-upload-examples-abort"></a>

다음 예시는 멀티파트 업로드를 중단하는 방법을 보여 줍니다.

#### AWS SDK 사용
<a name="directory-bucket-multipart-upload-abort-sdk"></a>

------
#### [ SDK for Java 2.x ]

다음 예시는 SDK for Java 2.x를 사용하여 멀티파트 업로드를 중단하는 방법을 보여 줍니다.

**Example**  

```
public static void abortMultiPartUploads( S3Client s3, String bucketName ) {

         try {
             ListMultipartUploadsRequest listMultipartUploadsRequest = ListMultipartUploadsRequest.builder()
                     .bucket(bucketName)
                     .build();

             ListMultipartUploadsResponse response = s3.listMultipartUploads(listMultipartUploadsRequest);
             ListMultipartUpload uploads = response.uploads();

             AbortMultipartUploadRequest abortMultipartUploadRequest;
             for (MultipartUpload upload: uploads) {
                 abortMultipartUploadRequest = AbortMultipartUploadRequest.builder()
                         .bucket(bucketName)
                         .key(upload.key())
                         .uploadId(upload.uploadId())
                         .build();

                 s3.abortMultipartUpload(abortMultipartUploadRequest);
             }

         } 
         
         catch (S3Exception e) {
             System.err.println(e.getMessage());
             System.exit(1);
         }
     }
```

------
#### [ SDK for Python ]

다음 예시는 SDK for Python을 사용하여 멀티파트 업로드를 중단하는 방법을 보여 줍니다.

**Example**  

```
import logging
import boto3
from botocore.exceptions import ClientError


def abort_multipart_upload(s3_client, bucket_name, key_name, upload_id):
    '''
    Aborts a partial multipart upload in a directory bucket.
    
    :param s3_client: boto3 S3 client
    :param bucket_name: Bucket where the multipart upload was initiated - for example, 'doc-example-bucket--usw2-az1--x-s3'
    :param key_name: Name of the object for which the multipart upload needs to be aborted
    :param upload_id: Multipart upload ID for the multipart upload to be aborted
    :return: True if the multipart upload was successfully aborted, False if not
    '''
    try:
        s3_client.abort_multipart_upload(
            Bucket = bucket_name,
            Key = key_name,
            UploadId = upload_id
        )
    except ClientError as e:
        logging.error(e)
        return False
    return True


if __name__ == '__main__':
    region = 'us-west-2'
    bucket_name = 'BUCKET_NAME'
    key_name = 'KEY_NAME'
        upload_id = 'UPLOAD_ID'
    s3_client = boto3.client('s3', region_name = region)
    if abort_multipart_upload(s3_client, bucket_name, key_name, upload_id):
        print (f'Multipart upload for object {key_name} in {bucket_name} bucket has been aborted')
    else:
        print (f'Unable to abort multipart upload for object {key_name} in {bucket_name} bucket')
```

------

#### AWS CLI 사용
<a name="directory-bucket-multipart-upload-complete-cli"></a>

다음 예시는 AWS CLI를 사용하여 멀티파트 업로드를 중단하는 방법을 보여 줍니다. 명령을 사용하려면 *사용자 입력 자리 표시자*를 사용자의 정보로 대체합니다.

```
aws s3api abort-multipart-upload --bucket bucket-base-name--zone-id--x-s3 --key KEY_NAME --upload-id "AS_mgt9RaQE9GEaifATue15dAAAAAAAAAAEMAAAAAAAAADQwNzI4MDU0MjUyMBYAAAAAAAAAAA0AAAAAAAAAAAH2AfYAAAAAAAAEAX5hFw-MAQAAAAB0OxUFeA7LTbWWFS8WYwhrxDxTIDN-pdEEq_agIHqsbg"
```

자세한 내용은 AWS Command Line Interface의 [abort-multipart-upload](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/abort-multipart-upload.html)를 참조하세요.

### 멀티파트 업로드 복사 작업 생성
<a name="directory-buckets-multipart-upload-examples-upload-part-copy"></a>

**참고**  
UploadPartCopy가 디렉터리 버킷의 새 객체 파트 복사본을 SSE-KMS로 암호화하려면 KMS 키(특히 [고객 관리형 키](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#customer-cmk))를 사용하여 디렉터리 버킷의 기본 암호화 구성으로 SSE-KMS를 지정해야 합니다. [AWS 관리형 키](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#aws-managed-cmk)(`aws/s3`)는 지원되지 않습니다. SSE-KMS 구성은 버킷 수명 기간 동안 디렉터리 버킷당 [고객 관리형 키](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#customer-cmk) 1개만 지원할 수 있습니다. SSE-KMS에 고객 관리형 키를 지정한 후에는 버킷의 SSE-KMS 구성을 위한 고객 관리형 키를 재정의할 수 없습니다. [UploadPartCopy](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html) 요청 헤더에서 SSE-KMS를 사용하여 새 객체 부분 사본에 대한 서버 측 암호화 설정을 지정할 수 없습니다. 또한, `CreateMultipartUpload` 요청에서 제공하는 요청 헤더는 대상 버킷의 기본 암호화 구성과 일치해야 합니다.
범용 버킷에서 디렉터리 버킷으로, 디렉터리 버킷에서 범용 버킷으로 또는 디렉터리 버킷 간에 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html)를 통해 SSE-KMS로 암호화된 객체를 복사하는 경우 S3 버킷 키는 지원되지 않습니다. 이 경우 Amazon S3는 KMS 암호화 개체에 대한 사본 요청이 있을 때마다 AWS KMS를 직접적으로 호출합니다.

다음 예제는 멀티파트 업로드를 사용하여 버킷 간 객체를 복사하는 방법을 보여줍니다.

#### AWS SDK 사용
<a name="directory-bucket-multipart-upload-copy-sdk"></a>

------
#### [ SDK for Java 2.x ]

다음 예시는 SDK for Java 2.x를 통해 멀티파트 업로드를 사용하여 프로그래밍 방식으로 버킷의 객체를 다른 버킷으로 복사하는 방법을 보여 줍니다.

**Example**  

```
/**
 * This method creates a multipart upload request that generates a unique upload ID that is used to track
 * all the upload parts.
 *
 * @param s3
 * @param bucketName
 * @param key
 * @return
 */
 private static String createMultipartUpload(S3Client s3, String bucketName, String key) {
        CreateMultipartUploadRequest createMultipartUploadRequest = CreateMultipartUploadRequest.builder()
                .bucket(bucketName)
                .key(key)
                .build();
        String uploadId = null;
        try {
            CreateMultipartUploadResponse response = s3.createMultipartUpload(createMultipartUploadRequest);
            uploadId = response.uploadId();
        } catch (S3Exception e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
        return uploadId;
  }

  /**
   * Creates copy parts based on source object size and copies over individual parts
   *
   * @param s3
   * @param sourceBucket
   * @param sourceKey
   * @param destnBucket
   * @param destnKey
   * @param uploadId
   * @return
   * @throws IOException
   */
    public static ListCompletedPart multipartUploadCopy(S3Client s3, String sourceBucket, String sourceKey, String destnBucket, String destnKey, String uploadId) throws IOException {

        // Get the object size to track the end of the copy operation.
        HeadObjectRequest headObjectRequest = HeadObjectRequest
                .builder()
                .bucket(sourceBucket)
                .key(sourceKey)
                .build();
        HeadObjectResponse response = s3.headObject(headObjectRequest);
        Long objectSize = response.contentLength();

        System.out.println("Source Object size: " + objectSize);

        // Copy the object using 20 MB parts.
        long partSize = 20 * 1024 * 1024;
        long bytePosition = 0;
        int partNum = 1;
        ListCompletedPart completedParts = new ArrayList<>();
        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);

            System.out.println("part no: " + partNum + ", bytePosition: " + bytePosition + ", lastByte: " + lastByte);

            // Copy this part.
            UploadPartCopyRequest req = UploadPartCopyRequest.builder()
                    .uploadId(uploadId)
                    .sourceBucket(sourceBucket)
                    .sourceKey(sourceKey)
                    .destinationBucket(destnBucket)
                    .destinationKey(destnKey)
                    .copySourceRange("bytes="+bytePosition+"-"+lastByte)
                    .partNumber(partNum)
                    .build();
            UploadPartCopyResponse res = s3.uploadPartCopy(req);
            CompletedPart part = CompletedPart.builder()
                    .partNumber(partNum)
                    .eTag(res.copyPartResult().eTag())
                    .build();
            completedParts.add(part);
            partNum++;
            bytePosition += partSize;
        }
        return completedParts;
    }


    public static void multipartCopyUploadTest(S3Client s3, String srcBucket, String srcKey, String destnBucket, String destnKey)  {
        System.out.println("Starting multipart copy for: " + srcKey);
        try {
            String uploadId = createMultipartUpload(s3, destnBucket, destnKey);
            System.out.println(uploadId);
            ListCompletedPart parts = multipartUploadCopy(s3, srcBucket, srcKey,destnBucket,  destnKey, uploadId);
            completeMultipartUpload(s3, destnBucket, destnKey, uploadId, parts);
            System.out.println("Multipart copy completed for: " + srcKey);
        } catch (Exception e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }
```

------
#### [ SDK for Python ]

다음 예시는 SDK for Python을 통해 멀티파트 업로드를 사용하여 프로그래밍 방식으로 버킷의 객체를 다른 버킷으로 복사하는 방법을 보여 줍니다.

**Example**  

```
import logging
import boto3
from botocore.exceptions import ClientError

def head_object(s3_client, bucket_name, key_name):
    '''
    Returns metadata for an object in a directory bucket

    :param s3_client: boto3 S3 client
    :param bucket_name: Bucket that contains the object to query for metadata
    :param key_name: Key name to query for metadata
    :return: Metadata for the specified object if successful, else None
    '''

    try:
        response = s3_client.head_object(
            Bucket = bucket_name,
            Key = key_name
        )
        return response
    except ClientError as e:
        logging.error(e)
        return None
    
def create_multipart_upload(s3_client, bucket_name, key_name):
    '''
    Create a multipart upload to a directory bucket

    :param s3_client: boto3 S3 client
    :param bucket_name: Destination bucket for the multipart upload
    :param key_name: Key name of the object to be uploaded
    :return: UploadId for the multipart upload if created successfully, else None
    '''
    
    try:
        mpu = s3_client.create_multipart_upload(Bucket = bucket_name, Key = key_name)
        return mpu['UploadId'] 
    except ClientError as e:
        logging.error(e)
        return None

def multipart_copy_upload(s3_client, source_bucket_name, key_name, target_bucket_name, mpu_id, part_size):
    '''
    Copy an object in a directory bucket to another bucket in multiple parts of a specified size
    
    :param s3_client: boto3 S3 client
    :param source_bucket_name: Bucket where the source object exists
    :param key_name: Key name of the object to be copied
    :param target_bucket_name: Destination bucket for copied object
    :param mpu_id: The UploadId returned from the create_multipart_upload call
    :param part_size: The size parts that the object will be broken into, in bytes. 
                      Minimum 5 MiB, Maximum 5 GiB. There is no minimum size for the last part of your multipart upload.
    :return: part_list for the multipart copy if all parts are copied successfully, else None
    '''
    
    part_list = []
    copy_source = {
        'Bucket': source_bucket_name,
        'Key': key_name
    }
    try:
        part_counter = 1
        object_size = head_object(s3_client, source_bucket_name, key_name)
        if object_size is not None:
            object_size = object_size['ContentLength']
        while (part_counter - 1) * part_size <object_size:
            bytes_start = (part_counter - 1) * part_size
            bytes_end = (part_counter * part_size) - 1
            upload_copy_part = s3_client.upload_part_copy (
                Bucket = target_bucket_name,
                CopySource = copy_source,
                CopySourceRange = f'bytes={bytes_start}-{bytes_end}',
                Key = key_name,
                PartNumber = part_counter,
                UploadId = mpu_id
            )
            part_list.append({'PartNumber': part_counter, 'ETag': upload_copy_part['CopyPartResult']['ETag']})
            part_counter += 1
    except ClientError as e:
        logging.error(e)
        return None
    return part_list

def complete_multipart_upload(s3_client, bucket_name, key_name, mpu_id, part_list):
    '''
    Completes a multipart upload to a directory bucket

    :param s3_client: boto3 S3 client
    :param bucket_name: Destination bucket for the multipart upload
    :param key_name: Key name of the object to be uploaded
    :param mpu_id: The UploadId returned from the create_multipart_upload call
    :param part_list: List of uploaded part numbers with associated ETags 
    :return: True if the multipart upload was completed successfully, else False
    '''
    
    try:
        s3_client.complete_multipart_upload(
            Bucket = bucket_name,
            Key = key_name,
            UploadId = mpu_id,
            MultipartUpload = {
                'Parts': part_list
            }
        )
    except ClientError as e:
        logging.error(e)
        return False
    return True

if __name__ == '__main__':
    MB = 1024 ** 2
    region = 'us-west-2'
    source_bucket_name = 'SOURCE_BUCKET_NAME'
    target_bucket_name = 'TARGET_BUCKET_NAME'
    key_name = 'KEY_NAME'
    part_size = 10 * MB
    s3_client = boto3.client('s3', region_name = region)
    mpu_id = create_multipart_upload(s3_client, target_bucket_name, key_name)
    if mpu_id is not None:
        part_list = multipart_copy_upload(s3_client, source_bucket_name, key_name, target_bucket_name, mpu_id, part_size)
        if part_list is not None:
            if complete_multipart_upload(s3_client, target_bucket_name, key_name, mpu_id, part_list):
                print (f'{key_name} successfully copied through multipart copy from {source_bucket_name} to {target_bucket_name}')
            else:
                print (f'Could not copy {key_name} through multipart copy from {source_bucket_name} to {target_bucket_name}')
```

------

#### AWS CLI 사용
<a name="directory-bucket-multipart-upload-copy-cli"></a>

다음 예시는 AWS CLI를 통해 멀티파트 업로드를 사용하여 프로그래밍 방식으로 버킷의 객체를 디렉터리 버킷으로 복사하는 방법을 보여 줍니다. 명령을 사용하려면 *사용자 입력 자리 표시자*를 사용자의 정보로 대체합니다.

```
aws s3api upload-part-copy --bucket bucket-base-name--zone-id--x-s3 --key TARGET_KEY_NAME --copy-source SOURCE_BUCKET_NAME/SOURCE_KEY_NAME --part-number 1 --upload-id "AS_mgt9RaQE9GEaifATue15dAAAAAAAAAAEMAAAAAAAAADQwNzI4MDU0MjUyMBYAAAAAAAAAAA0AAAAAAAAAAAH2AfYAAAAAAAAEBnJ4cxKMAQAAAABiNXpOFVZJ1tZcKWib9YKE1C565_hCkDJ_4AfCap2svg"
```

자세한 내용은 AWS Command Line Interface의 [upload-part-copy](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/upload-part-copy.html                         )를 참조하세요.

### 진행 중인 멀티파트 업로드 나열
<a name="directory-buckets-multipart-upload-examples-list"></a>

AWS SDK 또는 AWS CLI를 사용하여 디렉터리 버킷에 대해 진행 중인 멀티파트 업로드를 나열할 수 있습니다.

#### AWS SDK 사용
<a name="directory-bucket-multipart-upload-list-sdk"></a>

------
#### [ SDK for Java 2.x ]

다음 예시는 SDK for Java 2.x를 사용하여 진행 중인(완료되지 않은) 멀티파트 업로드를 나열하는 방법을 보여 줍니다.

**Example**  

```
 public static void listMultiPartUploads( S3Client s3, String bucketName) {
        try {
            ListMultipartUploadsRequest listMultipartUploadsRequest = ListMultipartUploadsRequest.builder()
                .bucket(bucketName)
                .build();
                
            ListMultipartUploadsResponse response = s3.listMultipartUploads(listMultipartUploadsRequest);
            List MultipartUpload uploads = response.uploads();
            for (MultipartUpload upload: uploads) {
                System.out.println("Upload in progress: Key = \"" + upload.key() + "\", id = " + upload.uploadId());
            }
      }
      catch (S3Exception e) {
            System.err.println(e.getMessage());
            System.exit(1);
      }
  }
```

------
#### [ SDK for Python ]

다음 예시는 SDK for Python을 사용하여 진행 중인(완료되지 않은) 멀티파트 업로드를 나열하는 방법을 보여 줍니다.

**Example**  

```
import logging
import boto3
from botocore.exceptions import ClientError

def list_multipart_uploads(s3_client, bucket_name):
    '''
    List any incomplete multipart uploads in a directory bucket in e specified gion

    :param s3_client: boto3 S3 client
    :param bucket_name: Bucket to check for incomplete multipart uploads
    :return: List of incomplete multipart uploads if there are any, None if not
    '''
    
    try:
        response = s3_client.list_multipart_uploads(Bucket = bucket_name)
        if 'Uploads' in response.keys():
            return response['Uploads']
        else:
            return None 
    except ClientError as e:
        logging.error(e)

if __name__ == '__main__':
    bucket_name = 'BUCKET_NAME'
    region = 'us-west-2'
    s3_client = boto3.client('s3', region_name = region)
    multipart_uploads = list_multipart_uploads(s3_client, bucket_name)
    if multipart_uploads is not None:
        print (f'There are {len(multipart_uploads)} ncomplete multipart uploads for {bucket_name}')
    else:
        print (f'There are no incomplete multipart uploads for {bucket_name}')
```

------

#### AWS CLI 사용
<a name="directory-bucket-multipart-upload-list-cli"></a>

다음 예시는 AWS CLI를 사용하여 진행 중인(완료되지 않은) 멀티파트 업로드를 나열하는 방법을 보여 줍니다. 명령을 사용하려면 *사용자 입력 자리 표시자*를 사용자의 정보로 대체합니다.

```
aws s3api list-multipart-uploads --bucket bucket-base-name--zone-id--x-s3
```

자세한 내용은 AWS Command Line Interface의 [list-multipart-uploads](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/list-multipart-uploads.html                         )를 참조하세요.

### 멀티파트 업로드의 부분 나열
<a name="directory-buckets-multipart-upload-examples-list-parts"></a>

다음 예시는 디렉터리 버킷에 대한 멀티파트 업로드의 부분을 나열하는 방법을 보여 줍니다.

#### AWS SDK 사용
<a name="directory-bucket-multipart-upload-list-parts-sdk"></a>

------
#### [ SDK for Java 2.x ]

다음 예시는 SDK for Java 2.x를 사용하여 디렉터리 버킷에 대한 멀티파트 업로드의 부분을 나열하는 방법을 보여 줍니다.

```
public static void listMultiPartUploadsParts( S3Client s3, String bucketName, String objKey, String uploadID) {
         
         try {
             ListPartsRequest listPartsRequest = ListPartsRequest.builder()
                 .bucket(bucketName)
                 .uploadId(uploadID)
                 .key(objKey)
                 .build();

             ListPartsResponse response = s3.listParts(listPartsRequest);
             ListPart parts = response.parts();
             for (Part part: parts) {
                 System.out.println("Upload in progress: Part number = \"" + part.partNumber() + "\", etag = " + part.eTag());
             }

         } 
         
         catch (S3Exception e) {
             System.err.println(e.getMessage());
             System.exit(1);
         }
         
         
     }
```

------
#### [ SDK for Python ]

다음 예시는 SDK for Python을 사용하여 디렉터리 버킷에 대한 멀티파트 업로드의 부분을 나열하는 방법을 보여 줍니다.

```
import logging
import boto3
from botocore.exceptions import ClientError

def list_parts(s3_client, bucket_name, key_name, upload_id):
    '''
    Lists the parts that have been uploaded for a specific multipart upload to a directory bucket.
    
    :param s3_client: boto3 S3 client
    :param bucket_name: Bucket that multipart uploads parts have been uploaded to
    :param key_name: Name of the object that has parts uploaded
    :param upload_id: Multipart upload ID that the parts are associated with
    :return: List of parts associated with the specified multipart upload, None if there are no parts
    '''
    parts_list = []
    next_part_marker = ''
    continuation_flag = True
    try:
        while continuation_flag:
            if next_part_marker == '':
                response = s3_client.list_parts(
                    Bucket = bucket_name,
                    Key = key_name,
                    UploadId = upload_id
                )
            else:
                response = s3_client.list_parts(
                    Bucket = bucket_name,
                    Key = key_name,
                    UploadId = upload_id,
                    NextPartMarker = next_part_marker
                )
            if 'Parts' in response:
                for part in response['Parts']:
                    parts_list.append(part)
                if response['IsTruncated']:
                    next_part_marker = response['NextPartNumberMarker']
                else:
                    continuation_flag = False
            else:
                continuation_flag = False
        return parts_list
    except ClientError as e:
        logging.error(e)
        return None

if __name__ == '__main__':
    region = 'us-west-2'
    bucket_name = 'BUCKET_NAME'
    key_name = 'KEY_NAME'
    upload_id = 'UPLOAD_ID'
    s3_client = boto3.client('s3', region_name = region)
    parts_list = list_parts(s3_client, bucket_name, key_name, upload_id)
    if parts_list is not None:
        print (f'{key_name} has {len(parts_list)} parts uploaded to {bucket_name}')
    else:
        print (f'There are no multipart uploads with that upload ID for {bucket_name} bucket')
```

------

#### AWS CLI 사용
<a name="directory-bucket-multipart-upload-list-parts-cli"></a>

다음 예시는 AWS CLI를 사용하여 디렉터리 버킷에 대한 멀티파트 업로드의 부분을 나열하는 방법을 보여 줍니다. 명령을 사용하려면 *사용자 입력 자리 표시자*를 사용자의 정보로 대체합니다.

```
aws s3api list-parts --bucket bucket-base-name--zone-id--x-s3 --key KEY_NAME --upload-id "AS_mgt9RaQE9GEaifATue15dAAAAAAAAAAEMAAAAAAAAADQwNzI4MDU0MjUyMBYAAAAAAAAAAA0AAAAAAAAAAAH2AfYAAAAAAAAEBSD0WBKMAQAAAABneY9yBVsK89iFkvWdQhRCcXohE8RbYtc9QvBOG8tNpA"
```

자세한 내용은 AWS Command Line Interface의 [list-parts](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/list-parts.html)를 참조하세요.

# 디렉터리 버킷에서 또는 디렉터리 버킷에 객체 복사
<a name="directory-buckets-objects-copy"></a>

복사 작업은 Amazon S3에 이미 저장되어 있는 객체의 복사본을 만듭니다. 디렉터리 버킷과 범용 버킷 간에 객체를 복사할 수 있습니다. 또한 버킷 내 및 동일한 유형의 버킷 간(예: 디렉터리 버킷에서 디렉터리 버킷으로)에 객체를 복사할 수 있습니다.

**참고**  
소스 또는 대상 버킷이 AWS 로컬 영역에 있는 경우 다른 AWS 리전에 객체를 복사할 수 없습니다. 소스 버킷과 대상 버킷의 상위 AWS 리전이 동일해야 합니다. 소스 버킷과 대상 버킷은 서로 다른 버킷 위치 유형(가용 영역 또는 로컬 영역)일 수 있습니다.

단일 원자성 작업으로 최대 5GB의 객체 복사본을 만들 수 있습니다. 그러나 5GB보다 큰 객체를 복사하려면 멀티파트 업로드 API 작업을 사용해야 합니다. 자세한 내용은 [디렉터리 버킷에 멀티파트 업로드 사용](s3-express-using-multipart-upload.md) 섹션을 참조하세요.

**권한**  
 객체를 복사하려면 다음 권한이 있어야 합니다.
+ 한 디렉터리 버킷에서 다른 디렉터리 버킷으로 객체를 복사하려면 `s3express:CreateSession` 권한이 있어야 합니다.
+ 디렉터리 버킷에서 범용 버킷으로 객체를 복사하려면 대상 버킷에 객체 사본을 쓸 수 있도록 `s3express:CreateSession` 권한과 `s3:PutObject` 권한이 있어야 합니다.
+ 범용 버킷에서 디렉터리 버킷으로 객체를 복사하려면 복사되는 소스 객체를 읽을 수 있도록 `s3express:CreateSession` 권한과 `s3:GetObject` 권한이 있어야 합니다.

   자세한 내용은 *Amazon Simple Storage Service API 참조*에서 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html)를 참조하세요.

**암호화**  
Amazon S3는 S3 버킷에 업로드되는 모든 새 객체를 자동으로 암호화합니다. S3 버킷의 기본 암호화 구성은 항상 활성화되어 있으며, 최소한 Amazon S3 관리형 키를 통한 서버 측 암호화(SSE-S3)로 설정되어 있습니다.

디렉터리 버킷의 경우 SSE-S3 및 AWS Key Management Service(AWS KMS) 키(SSE-KMS)를 사용한 서버 측 암호화가 지원됩니다. 대상 버킷이 디렉터리 버킷인 경우 대상 버킷의 기본 암호화는 원하는 암호화 구성을 사용하고 버킷 기본 암호화는 재정의하지 않는 것이 좋습니다. 그러면 새 객체가 원하는 암호화 설정으로 자동 암호화됩니다. 또한, 범용 버킷에서 디렉터리 버킷으로, 디렉터리 버킷에서 범용 버킷으로 또는 디렉터리 버킷 간에 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html)를 통해 SSE-KMS로 암호화된 객체를 복사하는 경우 S3 버킷 키는 지원되지 않습니다. 이 경우 Amazon S3는 KMS 암호화 개체에 대한 사본 요청이 있을 때마다 AWS KMS를 직접적으로 호출합니다. 디렉터리 버킷의 암호화 재정의 동작에 대한 자세한 내용은 [Specifying server-side encryption with AWS KMS for new object uploads](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-specifying-kms-encryption.html)를 참조하세요.

범용 버킷의 경우 SSE-S3(기본값), AWS Key Management Service(AWS KMS) 키를 사용한 서버 측 암호화(SSE-KMS), AWS KMS 키를 사용한 이중 계층 서버 측 암호화(DSSE-KMS) 또는 고객 제공 키를 사용한 서버 측 암호화(SSE-C)를 사용할 수 있습니다.

디렉터리 버킷(소스 또는 대상 버킷)에 대해 DSSE-KMS 또는 SSE-C를 사용하도록 지정하는 복사 요청을 하면 응답에 오류가 반환됩니다.

**Tags**  
디렉터리 버킷은 태그를 지원하지 않습니다. 범용 버킷의 태그가 있는 객체를 디렉터리 버킷으로 복사하면 HTTP `501 (Not Implemented)` 응답이 표시됩니다. 자세한 내용은 *Amazon Simple Storage Service API 참조*에서 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html)를 참조하세요.

**ETag**  
S3 Express One Zone의 엔터티 태그(ETag)는 임의의 영숫자 문자열이며 MD5 체크섬이 아닙니다. 객체 무결성을 보장하려면 추가 체크섬을 사용하세요.

**추가 체크섬**  
S3 Express One Zone은 업로드 또는 다운로드 중에 데이터를 검증하는 데 사용하는 체크섬 알고리즘을 선택할 수 있는 옵션을 제공합니다. SHA(보안 해시 알고리즘) 또는 CRC(순환 중복 검사) 데이터 무결성 확인 알고리즘(CRC32, CRC32C, SHA-1, SHA-256) 중 하나를 선택할 수 있습니다. MD5 기반 체크섬은 S3 Express One Zone 스토리지 클래스에서 지원되지 않습니다.

자세한 내용은 [S3 추가 체크섬 모범 사례](s3-express-optimizing-performance.md#s3-express-optimizing-performance-checksums) 섹션을 참조하세요.

**지원되는 기능**  
S3 Express One Zone에 지원되는 Amazon S3 기능에 대한 자세한 내용은 [디렉터리 버킷의 차이점](s3-express-differences.md) 섹션을 참조하세요.

## S3 콘솔 사용(디렉터리 버킷에 복사)
<a name="directory-bucket-copy-console"></a>

**참고**  
콘솔을 사용하여 디렉터리 버킷에 객체를 복사할 때의 규제 및 제한은 다음과 같습니다.  
`Copy` 작업은 지정된 폴더 내의 모든 객체(접두사)에 적용됩니다. 작업이 진행되는 동안 이 폴더에 추가된 객체가 영향을 받을 수 있습니다.
고객 제공 암호화 키(SSE-C)로 암호화된 객체는 S3 콘솔을 사용하여 복사할 수 없습니다. SSE-C로 암호화된 객체를 복사하려면 AWS CLI, AWS SDK 또는 Amazon S3 REST API를 사용합니다.
복사된 객체에는 원본 객체의 Object Lock 설정이 유지되지 않습니다.
객체를 복사하는 버킷이 S3 객체 소유권에 대해 버킷 소유자 적용 설정을 사용하는 경우 객체 ACL은 지정된 대상에 복사되지 않습니다.
S3 객체 소유권에 대한 버킷 소유자 적용 설정을 사용하는 버킷에 객체를 복사하려면 소스 버킷도 버킷 소유자 적용 설정을 사용하거나 다른 AWS 계정 및 그룹에 부여된 객체 ACL을 제거해야 합니다.
범용 버킷에서 디렉터리 버킷으로 복사된 객체는 객체 태그, ACL 또는 Etag 값을 유지하지 않습니다. 체크섬 값은 복사할 수 있지만, Etag와 동일하지는 않습니다. 체크섬 값은 추가되었을 때와 비교하여 변경될 수 있습니다.
 디렉터리 버킷으로 복사되는 모든 객체가 S3 객체 소유권에 대해 버킷 소유자 적용 설정을 사용합니다.

**범용 버킷 또는 디렉토리 버킷에서 디렉토리 버킷으로 개체를 복사하는 방법**

1. AWS Management Console에 로그인한 후 [https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/)에서 S3 콘솔을 엽니다.

1. 왼쪽 탐색 창에서 객체를 복사할 소스 버킷 유형은 다음과 같습니다.
   + 범용 버킷에서 복사하려면 **범용 버킷** 탭을 선택합니다.
   + 범용 버킷에서 복사하려면 **디렉터리 버킷** 탭을 선택합니다.

1. 복사할 객체가 포함된 범용 버킷 또는 디렉터리 버킷을 선택합니다.

1. **객체(Objects)** 탭을 선택합니다. **객체** 페이지에서 복사할 객체 이름 왼쪽에 있는 확인란을 선택합니다.

1. **작업** 메뉴에서 **복사**를 선택합니다.

   **복사** 페이지가 나타납니다.

1. **대상**에서 대상 유형에 맞는 **디렉터리 버킷**을 선택합니다. 대상 경로를 지정하려면 **S3 찾아보기**를 선택하고 대상으로 이동한 후 대상 왼쪽에 있는 옵션 버튼을 선택합니다. 오른쪽 하단 모서리에서 **대상 선택(Choose destination)**을 선택합니다.

   또는 대상 경로를 입력합니다.

1. **추가 복사 설정**에서 **소스 설정 복사**, **설정 지정 안 함** 또는 **설정 지정** 중 원하는 것을 선택합니다. **소스 설정 복사**가 기본 옵션입니다. 소스 설정 속성 없이 객체만 복사하려면 **설정 지정 안 함**을 선택합니다. 서버 측 암호화, 체크섬 및 메타데이터에 대한 설정을 지정하려면 **설정 지정**을 선택합니다.

1. 오른쪽 하단 모서리에서 **복사(Copy)**를 선택합니다. Amazon S3가 객체를 대상에 복사합니다.

## S3 콘솔 사용(범용 버킷에 복사)
<a name="directory-bucket-copy-console"></a>

**참고**  
콘솔을 사용하여 범용 버킷에 객체를 복사할 때의 규제 및 제한은 다음과 같습니다.  
`Copy` 작업은 지정된 폴더 내의 모든 객체(접두사)에 적용됩니다. 작업이 진행되는 동안 이 폴더에 추가된 객체가 영향을 받을 수 있습니다.
고객 제공 암호화 키(SSE-C)로 암호화된 객체는 S3 콘솔을 사용하여 복사할 수 없습니다. SSE-C로 암호화된 객체를 복사하려면 AWS CLI, AWS SDK 또는 Amazon S3 REST API를 사용합니다.
복사된 객체에는 원본 객체의 Object Lock 설정이 유지되지 않습니다.
객체를 복사하는 버킷이 S3 객체 소유권에 대해 버킷 소유자 적용 설정을 사용하는 경우 객체 ACL은 지정된 대상에 복사되지 않습니다.
S3 객체 소유권에 대한 버킷 소유자 적용 설정을 사용하는 버킷에 객체를 복사하려면 소스 버킷도 버킷 소유자 적용 설정을 사용하거나 다른 AWS 계정 및 그룹에 부여된 객체 ACL을 제거해야 합니다.

**디렉터리 버킷의 객체를 범용 버킷으로 복사하는 방법**

1. AWS Management Console에 로그인한 후 [https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/)에서 S3 콘솔을 엽니다.

1. 왼쪽 탐색 창에서 **버킷(Buckets)**을 선택합니다.

1. **디렉터리 버킷** 탭을 선택합니다.

1. 삭제할 객체가 포함된 디렉터리 버킷을 선택합니다.

1. **객체(Objects)** 탭을 선택합니다. **객체** 페이지에서 복사할 객체 이름 왼쪽에 있는 확인란을 선택합니다.

1. **작업** 메뉴에서 **복사**를 선택합니다.

    

1. **대상**에서 대상 유형에 맞는 **범용 버킷**을 선택합니다. 대상 경로를 지정하려면 **S3 찾아보기**를 선택하고 대상으로 이동한 후 대상 왼쪽에 있는 옵션 버튼을 선택합니다. 오른쪽 하단 모서리에서 **대상 선택(Choose destination)**을 선택합니다.

   또는 대상 경로를 입력합니다.

1. **추가 복사 설정**에서 **소스 설정 복사**, **설정 지정 안 함** 또는 **설정 지정** 중 원하는 것을 선택합니다. **소스 설정 복사**가 기본 옵션입니다. 소스 설정 속성 없이 객체만 복사하려면 **설정 지정 안 함**을 선택합니다. 스토리지 클래스, ACL, 객체 태그, 메타데이터, 서버 측 암호화 및 추가 체크섬에 대한 설정을 지정하려면 **설정 지정**을 선택합니다.

1. 오른쪽 하단 모서리에서 **복사(Copy)**를 선택합니다. Amazon S3가 객체를 대상에 복사합니다.

## AWS SDK 사용
<a name="directory-bucket-copy-sdks"></a>

------
#### [ SDK for Java 2.x ]

**Example**  

```
 public static void copyBucketObject (S3Client s3, String sourceBucket, String objectKey, String targetBucket) {
      CopyObjectRequest copyReq = CopyObjectRequest.builder()
          .sourceBucket(sourceBucket)
          .sourceKey(objectKey)
          .destinationBucket(targetBucket)
          .destinationKey(objectKey)
          .build();
       String temp = "";
                                             
       try {
           CopyObjectResponse copyRes = s3.copyObject(copyReq);
           System.out.println("Successfully copied " + objectKey +" from bucket " + sourceBucket +" into bucket "+targetBucket);
       }
       
       catch (S3Exception e) {
           System.err.println(e.awsErrorDetails().errorMessage());
           System.exit(1);
       }
 }
```

------

## AWS CLI 사용
<a name="directory-copy-object-cli"></a>

다음 `copy-object` 예시 명령은 AWS CLI를 사용하여 버킷의 객체를 다른 버킷으로 복사하는 방법을 보여 줍니다. 버킷 유형 간에 객체를 복사할 수 있습니다. 이 명령을 실행하려면 user input placeholders를 사용자의 정보로 대체합니다.

```
aws s3api copy-object --copy-source SOURCE_BUCKET/SOURCE_KEY_NAME --key TARGET_KEY_NAME --bucket TARGET_BUCKET_NAME
```

자세한 내용은 *AWS CLI 명령 참조*의 [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/copy-object.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/copy-object.html) 섹션을 참조하십시오.

# 디렉터리 버킷에서 객체 삭제
<a name="directory-bucket-delete-object"></a>

Amazon S3 콘솔, AWS Command Line Interface(AWS CLI) 또는 AWS SDK를 사용하여 Amazon S3 디렉터리 버킷에서 객체를 삭제할 수 있습니다. 자세한 내용은 [디렉터리 버킷 작업](directory-buckets-overview.md) 및 [S3 Express One Zone](directory-bucket-high-performance.md#s3-express-one-zone)(을)를 참조하세요.

**주의**  
객체 삭제는 실행 취소할 수 없습니다.
이 작업은 지정된 모든 객체를 삭제합니다. 폴더를 삭제할 때 폴더에 새 객체를 추가하기 전에 삭제 작업이 완료될 때까지 기다립니다. 그러지 않으면 새 객체도 삭제될 수 있습니다.

**참고**  
디렉터리 버킷에서 프로그래밍 방식으로 여러 객체를 삭제할 경우 다음에 유의하세요.  
`DeleteObjects` 요청의 객체 키는 공백이 아닌 문자를 하나 이상 포함해야 합니다. 공백 문자로만 구성된 문자열은 지원되지 않습니다.
`DeleteObjects` 요청의 객체 키에는 유니코드 제어 문자를 포함할 수 없습니다. 단, 줄바꿈(`\n`), 탭(`\t`) 및 캐리지 리턴(`\r`)은 예외입니다.

## S3 콘솔 사용
<a name="delete-object-directory-bucket-console"></a>

**객체 삭제**

1. AWS Management Console에 로그인한 후 [https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/)에서 S3 콘솔을 엽니다.

1. 왼쪽 탐색 창에서 **디렉터리 버킷**을 선택합니다.

1. 삭제할 객체가 포함된 디렉터리 버킷을 선택합니다.

1. **객체(Objects)** 탭을 선택합니다. **객체** 목록에서 삭제할 하나 또는 여러 객체 옆의 확인란을 선택합니다.

1. **삭제**를 선택합니다.

   

1. **객체 삭제** 페이지에서 텍스트 상자에 **permanently delete**를 입력합니다.

1. **객체 삭제**를 선택합니다.

## AWS SDK 사용
<a name="delete-object-directory-bucket-sdks"></a>

------
#### [ SDK for Java 2.x ]

**Example**  
다음 예시에서는 AWS SDK for Java 2.x를 사용하여 디렉터리 버킷의 객체를 삭제합니다.  

```
static void deleteObject(S3Client s3Client, String bucketName, String objectKey) {


        
        try {
            
            DeleteObjectRequest del = DeleteObjectRequest.builder()
                    .bucket(bucketName)
                    .key(objectKey)
                    .build();

            s3Client.deleteObject(del);
            
            System.out.println("Object " + objectKey + " has been deleted");
            
            
        } catch (S3Exception e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
        
    }
```

------
#### [ SDK for Python ]

**Example**  
다음 예시에서는 AWS SDK for Python (Boto3)을 사용하여 디렉터리 버킷의 객체를 삭제합니다.  

```
import logging
import boto3
from botocore.exceptions import ClientError

def delete_objects(s3_client, bucket_name, objects):
    '''
    Delete a list of objects in a directory bucket

    :param s3_client: boto3 S3 client
    :param bucket_name: Bucket that contains objects to be deleted; for example, 'doc-example-bucket--usw2-az1--x-s3'
    :param objects: List of dictionaries that specify the key names to delete
    :return: Response output, else False
    '''

    try:
        response = s3_client.delete_objects(
            Bucket = bucket_name,
            Delete = {
                'Objects': objects
            } 
        )
        return response
    except ClientError as e:
        logging.error(e)
        return False
    

if __name__ == '__main__':
    region = 'us-west-2'
    bucket_name = 'BUCKET_NAME'
    objects = [
        {
            'Key': '0.txt'
        },
        {
            'Key': '1.txt'
        },
        {
            'Key': '2.txt'
        },
        {
            'Key': '3.txt'
        },
        {
            'Key': '4.txt'
        }
    ]
    
    s3_client = boto3.client('s3', region_name = region)
    results = delete_objects(s3_client, bucket_name, objects)
    if results is not None:
        if 'Deleted' in results:
            print (f'Deleted {len(results["Deleted"])} objects from {bucket_name}')
        if 'Errors' in results:
            print (f'Failed to delete {len(results["Errors"])} objects from {bucket_name}')
```

------

## AWS CLI 사용
<a name="directory-download-object-cli"></a>

다음 `delete-object` 예시 명령에서는 AWS CLI를 사용하여 디렉터리 버킷에서 객체를 삭제하는 방법을 보여 줍니다. 이 명령을 실행하려면 `user input placeholders`를 사용자의 정보로 대체합니다.

```
aws s3api delete-object --bucket bucket-base-name--zone-id--x-s3 --key KEY_NAME 
```

자세한 내용은 *AWS CLI 명령 참조*의 [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/delete-object.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/delete-object.html) 섹션을 참조하십시오.

다음 `delete-objects` 예시 명령에서는 AWS CLI를 사용하여 디렉터리 버킷에서 객체를 삭제하는 방법을 보여줍니다. 이 명령을 실행하려면 `user input placeholders`를 사용자의 정보로 대체합니다.

`delete.json` 파일은 다음과 같습니다.

```
{
    "Objects": [
        {
            "Key": "0.txt"
        },
        {
            "Key": "1.txt"
        },
        {
            "Key": "2.txt"
        },
        {
            "Key": "3.txt"
        }
    ]
}
```

`delete-objects` 예시 명령은 다음과 같습니다.

```
aws s3api delete-objects --bucket bucket-base-name--zone-id--x-s3 --delete file://delete.json 
```

자세한 내용은 *AWS CLI 명령 참조*의 [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/delete-objects.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/delete-objects.html) 섹션을 참조하십시오.

# 디렉터리 버킷에서 객체 다운로드
<a name="directory-buckets-objects-GetExamples"></a>

 다음 코드 예제는 `GetObject` API 작업을 사용하여 Amazon S3 디렉터리 버킷의 객체에서 데이터를 읽는(다운로드하는) 방법을 보여줍니다.

## AWS SDK 사용
<a name="directory-bucket-copy-sdks"></a>

------
#### [ SDK for Java 2.x ]

**Example**  
다음 코드 예제는 AWS SDK for Java 2.x를 사용하여 디렉터리 버킷의 객체에서 데이터를 읽는 방법을 보여줍니다.  

```
public static void getObject(S3Client s3Client, String bucketName, String objectKey) {
     try {
         GetObjectRequest objectRequest = GetObjectRequest
            .builder()
            .key(objectKey)
            .bucket(bucketName)
            .build();
            
         ResponseBytes GetObjectResponse objectBytes = s3Client.getObjectAsBytes(objectRequest);
         byte[] data = objectBytes.asByteArray();
         
         //Print object contents to console
         String s = new String(data, StandardCharsets.UTF_8);
         System.out.println(s);
    }
    
    catch (S3Exception e) {
        System.err.println(e.awsErrorDetails().errorMessage());
        System.exit(1);
    }
}
```

------
#### [ SDK for Python ]

**Example**  
다음 코드 예제는 AWS SDK for Python (Boto3)을 사용하여 디렉터리 버킷의 객체에서 데이터를 읽는 방법을 보여줍니다.  

```
import boto3
from botocore.exceptions import ClientError
from botocore.response import StreamingBody

def get_object(s3_client: boto3.client, bucket_name: str, key_name: str) -> StreamingBody:
    """
    Gets the object.
    :param s3_client:
    :param bucket_name: The bucket that contains the object. 
    :param key_name: The key of the object to be downloaded.
    :return: The object data in bytes.
    """
    try:
        response = s3_client.get_object(Bucket=bucket_name, Key=key_name)
        body = response['Body'].read()
        print(f"Got object '{key_name}' from bucket '{bucket_name}'.")
    except ClientError:
        print(f"Couldn't get object '{key_name}' from bucket '{bucket_name}'.")
        raise
    else:
        return body
        
def main():
    s3_client = boto3.client('s3')
    resp = get_object(s3_client, 'doc-example-bucket--use1-az4--x-s3', 'sample.txt')
    print(resp)
    
if __name__ == "__main__":
     main()
```

------

## AWS CLI 사용
<a name="directory-download-object-cli"></a>

다음 `get-object` 예제 명령은 AWS CLI를 사용하여 Amazon S3에서 객체를 다운로드하는 방법을 보여줍니다. 이 명령은 디렉터리 버킷 `bucket-base-name--zone-id--x-s3`에서 `KEY_NAME` 객체를 가져옵니다. 객체는 `LOCAL_FILE_NAME`라는 파일로 다운로드됩니다. 이 명령을 실행하려면 `user input placeholders`를 사용자의 정보로 대체합니다.

```
aws s3api get-object --bucket bucket-base-name--zone-id--x-s3 --key KEY_NAME LOCAL_FILE_NAME
```

자세한 내용은 *AWS CLI 명령 참조*의 [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/get-object.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/get-object.html) 섹션을 참조하십시오.

# 객체 디렉터리 버킷을 공유하기 위해 미리 서명된 URL 생성
<a name="directory-buckets-objects-generate-presigned-url-Examples"></a>

 다음 코드 예시에서는 Amazon S3 디렉터리 버킷에서 객체를 공유하기 위해 미리 서명된 URLs을 생성하는 방법을 보여줍니다.

## AWS CLI 사용
<a name="directory-download-object-cli"></a>

다음 예시 명령은 AWS CLI를 사용하여 Amazon S3의 객체에 대해 미리 서명된 URL을 생성하는 방법을 보여줍니다. 이 명령은 `bucket-base-name--zone-id--x-s3` 디렉터리 버킷에서 `KEY_NAME` 객체에 대해 미리 서명된 URL을 생성합니다. 이 명령을 실행하려면 `user input placeholders`를 사용자의 정보로 대체합니다.

```
aws s3 presign s3://bucket-base-name--zone-id--x-s3/KEY_NAME --expires-in 7200
```

자세한 내용은 *AWS CLI 명령 참조*의 [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/presign.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/presign.html) 섹션을 참조하십시오.

# 디렉터리 버킷에서 객체 메타데이터 검색
<a name="directory-buckets-objects-HeadObjectExamples"></a>

다음 AWS SDK 및 AWS CLI 예시는 `HeadObject` 및 `GetObjectAttributes` API 작업을 사용하여 객체 자체를 반환하지 않고 Amazon S3 디렉터리 버킷의 객체에서 메타데이터를 검색하는 방법을 보여줍니다.

## AWS SDK 사용
<a name="directory-bucket-copy-sdks"></a>

------
#### [ SDK for Java 2.x ]

**Example**  

```
public static void headObject(S3Client s3Client, String bucketName, String objectKey) {
     try {
         HeadObjectRequest headObjectRequest = HeadObjectRequest
                 .builder()
                 .bucket(bucketName)
                 .key(objectKey)
                 .build();
         HeadObjectResponse response = s3Client.headObject(headObjectRequest);
         System.out.format("Amazon S3 object: \"%s\" found in bucket: \"%s\" with ETag: \"%s\"", objectKey, bucketName, response.eTag());
     }
     catch (S3Exception e) {
         System.err.println(e.awsErrorDetails().errorMessage());
```

------

## AWS CLI 사용
<a name="directory-head-object-cli"></a>

다음 `head-object` 예시 명령은 AWS CLI를 사용하여 객체에서 메타데이터를 검색하는 방법을 보여 줍니다. 이 명령을 실행하려면 `user input placeholders`를 사용자의 정보로 대체합니다.

```
aws s3api head-object --bucket bucket-base-name--zone-id--x-s3 --key KEY_NAME
```

자세한 내용은 *AWS CLI 명령 참조*의 [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/head-object.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/head-object.html) 섹션을 참조하십시오.

다음 `get-object-attributes` 예시 명령은 AWS CLI를 사용하여 객체에서 메타데이터를 검색하는 방법을 보여 줍니다. 이 명령을 실행하려면 `user input placeholders`를 사용자의 정보로 대체합니다.

```
aws s3api get-object-attributes --bucket bucket-base-name--zone-id--x-s3 --key KEY_NAME --object-attributes "StorageClass" "ETag" "ObjectSize"
```

자세한 내용은 *AWS CLI 명령 참조*의 [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/get-object-attributes.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/get-object-attributes.html) 섹션을 참조하십시오.

# 디렉터리 버킷에서 객체 나열
<a name="directory-buckets-objects-listobjectsExamples"></a>

 다음 코드 예시는 `ListObjectsV2` API 작업을 사용하여 Amazon S3 디렉터리 버킷의 객체를 나열하는 방법을 보여줍니다.

## AWS CLI 사용
<a name="directory-download-object-cli"></a>

다음 `list-objects-v2` 예시 명령은 AWS CLI를 사용하여 Amazon S3에서 객체를 나열하는 방법을 보여줍니다. 이 명령은 `bucket-base-name--zone-id--x-s3` 디렉터리 버 에서 객체를 나열합니다. 이 명령을 실행하려면 `user input placeholders`를 사용자의 정보로 대체합니다.

```
aws s3api list-objects-v2 --bucket bucket-base-name--zone-id--x-s3
```

자세한 내용은 *AWS CLI 명령 참조*의 [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/list-objects-v2.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/list-objects-v2.html) 섹션을 참조하십시오.