

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 上傳物件
<a name="upload-objects"></a>

當您將檔案上傳至 Amazon S3 時，該檔案會另存為 S3 *物件*。物件是由檔案資料與說明物件的中繼資料所組成。儲存貯體中可以有不限數目的物件。您需要儲存貯體的寫入許可，才能將檔案上傳至 Amazon S3 儲存貯體。如需存取許可的詳細資訊，請參閱「[Amazon S3 的身分和存取管理](security-iam.md)」。

您可以將任何檔案類型 (影像、備份、資料、影片等) 上傳至 S3 儲存貯體。使用 Amazon S3 主控台可上傳的檔案大小上限為 160 GB。若要上傳大於 160 GB 的檔案，請使用 AWS Command Line Interface (AWS CLI)、 AWS SDKs或 Amazon S3 REST API。

如果上傳物件的金鑰名稱已存在於啟用版本控制的儲存貯體中，Amazon S3 會建立另一個物件版本，而不是取代現有的物件。如需啟用版本控制的詳細資訊，請參閱[在儲存貯體上啟用版本控制](manage-versioning-examples.md)。

 視上傳資料大小之不同，Amazon S3 提供下列選項：
+ **使用 AWS SDKs、REST API 或 ，在單一操作中上傳物件 AWS CLI** – 透過單一`PUT`操作，您可以上傳大小上限為 5 GB 的單一物件。
+ **使用 Amazon S3 主控台上傳單一物件****–** – 使用 Amazon S3 主控台，您可以上傳大小最多 160 GB 的單一物件。
+ **使用 AWS SDKs、REST API 或 分段上傳物件 AWS CLI**** –** 使用分段上傳 API 操作，您可以上傳單一大型物件，大小上限為 50 TB。

  分段上傳 API 操作是專為改善較大型物件上傳體驗所設計。您可以上傳零件中的物件。這些物件部分可個別、依任何順序以及同時上傳。對於大小從 5 MB 到 50 TB 的物件，您可以使用分段上傳。如需詳細資訊，請參閱[在 Amazon S3 中使用分段上傳來上傳和複製物件](mpuoverview.md)。

若要上傳大於 5 TB 的檔案，請在 Java v1/v2、Python 或 AWS CLI SDKs中使用 S3 Transfer Manager。為了獲得最佳效能，請將最新的 AWS Common Runtime (CRT) 與這些 SDK 搭配使用，這些 SDKs 已針對更好的資源使用率進行最佳化。

從記憶體串流上傳大型物件時，CRT 會在記憶體中緩衝每個部分最多 5 GB，依配置的記憶體限制整體輸送量。您可以使用組態選項調整 CRT 記憶體限制，例如 `maxNativeMemoryLimitInBytes` for Java SDK。對於從磁碟上傳，CRT 會自動切換到直接磁碟串流，而不是中繼部分緩衝，從而改善記憶體用量。此行為會自動為大型物件啟用，但也可以透過請求參數為較小的檔案啟用，例如 `should_stream` for AWS CLI 和 `CRT_MEMORY_BUFFER_DISABLED` for Java SDK。

上傳物件時，根據預設，物件使用伺服器端加密與 Amazon S3 受管金鑰 (SSE-S3) 進行自動加密。當您下載物件時，該物件會解密。如需詳細資訊，請參閱[對 Amazon S3 儲存貯體設定預設伺服器端加密行為](bucket-encryption.md)及[使用加密來保護資料](UsingEncryption.md)。

當您上傳物件時，如果您想要使用不同類型的預設加密，也可以在 S3 `PUT`請求中使用 AWS Key Management Service (AWS KMS) 金鑰 (SSE-KMS) 指定伺服器端加密，或在目的地儲存貯體中設定預設加密組態，以使用 SSE-KMS 加密您的資料。如需 SSE-KMS 的詳細資訊，請參閱「[使用 AWS KMS (SSE-KMS) 指定伺服器端加密](specifying-kms-encryption.md)」。若您想要使用其他帳戶的 KMS 金鑰，您必須具有該金鑰的使用權限。如需詳細了解 KMS 金鑰跨帳戶權限，請參閱《AWS Key Management Service 開發人員指南》**中的[建立其他帳戶可使用的 KMS 金鑰](https://docs.aws.amazon.com//kms/latest/developerguide/key-policy-modifying-external-accounts.html#cross-account-console)。

如果您在 Amazon S3 中遇到「存取遭拒 (403 Forbidden)」錯誤，請參閱[對 Amazon S3 中的存取遭拒 (403 Forbidden) 錯誤進行故障診斷](troubleshoot-403-errors.md)以進一步了解其常見原因。

## 上傳物件
<a name="upload-objects-procedure"></a>

### 使用 S3 主控台
<a name="upload-objects-by-drag-and-drop"></a>

此程序說明如何使用主控台，將物件和資料夾上傳至 Amazon S3 儲存貯體。

上傳物件時，物件索引鍵名稱為檔案名稱加上任何選擇性的字首。在 Amazon S3 主控台中，您可以建立資料夾來整理物件。在 Amazon S3 中，資料夾表示為物件索引鍵名稱中的字首。如果您在 Amazon S3 主控台中將個別物件上傳到資料夾，則物件索引鍵名稱中會包含該資料夾名稱。

例如，如果您將名為 `sample1.jpg` 的物件上傳到名為 `backup` 的資料夾，則索引鍵名稱為 `backup/sample1.jpg`。不過，此物件在主控台中會顯示為 `sample1.jpg` 資料夾中的 `backup`。如需金鑰名稱的詳細資訊，請參閱「[使用物件中繼資料](UsingMetadata.md)」。

**注意**  
如果您在 Amazon S3 主控台中重新命名物件或變更物件的任何屬性 (例如**儲存類別**、**加密**或**中繼資料**)，則會建立新物件來取代舊的物件。如果啟用 S3 版本控制，則系統會建立物件的新版本，且現有物件會變成較舊的版本。變更屬性的角色也會成為新物件 (或物件版本) 的擁有者。

當您上傳資料夾時，Amazon S3 會將指定資料夾中的所有檔案與子資料夾上傳至您的儲存貯體。然後會指派一個由已上傳檔案名稱與資料夾名稱所組成的物件金鑰名稱。例如，如果您上傳一個名為 `/images` 的資料夾，其中包含兩個檔案 `sample1.jpg` 與 `sample2.jpg`，Amazon S3 會上傳檔案，然後指派對應的索引鍵名稱 `images/sample1.jpg` 與 `images/sample2.jpg`。金鑰名稱包含資料夾名稱作為字首。Amazon S3 主控台只會顯示最後一個 `/` 後面的金鑰名稱部分。例如，在 `images` 資料夾中，`images/sample1.jpg` 與 `images/sample2.jpg` 物件會顯示為 `sample1.jpg` 與 `sample2.jpg`。<a name="upload-files-folders"></a>

**將資料夾和檔案上傳至 S3 儲存貯體**

1. 登入 AWS 管理主控台 並開啟位於 https：//[https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/) 的 Amazon S3 主控台。

1. 在左側導覽窗格中，選擇 **Buckets** (儲存貯體)。

1. 在 **Buckets** (儲存貯體) 清單中，選擇您要上傳資料夾或檔案的目標儲存貯體名稱。

1. 選擇 **Upload** (上傳)。

1. 在 **Upload** (上傳) 視窗中，執行下列其中一個操作：
   + 將檔案和資料夾拖放至 **Upload** (上傳) 視窗。
   + 選擇**新增檔案**或**新增資料夾**，選擇要上傳的檔案或資料夾，然後選擇**開啟**。

1. 若要啟用多版本設定，請在 **Destination** (目的地) 下選擇 **Enable Bucket Versioning** (啟用儲存貯體版本控制)。

1. 若要上傳列出的檔案和資料夾，而不設定其他上傳選項，請選擇頁面底部的 **Upload** (上傳)。

   Amazon S3 會上傳您的物件和資料夾。上傳完成後，您可以在**上傳：狀態**頁面上看到成功訊息。<a name="configure-additional-properties"></a>

**設定其他物件屬性**

1. 若要變更存取控制清單許可，請選擇**Permissions** (許可)。

1. 在**存取控制清單 (ACL)**中，編輯許可。

   如需物件存取許可的資訊，請參閱「[使用 S3 主控台來設定物件的 ACL 許可](managing-acls.md#set-object-permissions)」。您可以針對您上傳的所有檔案，將物件的讀取存取許可授予大眾 (全世界的所有人)。但是，建議不要變更公有讀取存取的預設設定。授予公有讀取存取適用於一小部分的使用情況，例如當儲存貯體用於網站時。您一律可以在上傳物件之後變更物件許可。

1. 若要設定其他附加屬性，請選擇**Properties** (屬性)。

1. 在**儲存類別**下，選擇您要上傳的檔案的儲存類別。

   如需儲存體方案的詳細資訊，請參閱「[了解和管理 Amazon S3 儲存類別](storage-class-intro.md)」。

1. 若要更新物件的加密設定，請在 **Server-side encryption settings** (伺服器端加密設定) 下，執行下列操作。

   1. 選擇 **Specify an encryption key** (指定加密金鑰)。

   1. 在**加密設定**底下，選擇**使用預設加密的儲存貯體設定**或**覆寫預設加密的儲存貯體設定**。

   1. 若您選擇**覆寫預設加密的儲存貯體設定**，則您必須設定下列加密設定。
      + 若要使用 Amazon S3 管理的金鑰加密上傳的檔案，請選擇 **Amazon S3 受管金鑰 (SSE-S3)**。

        如需詳細資訊，請參閱[使用 Amazon S3 受管金鑰 (SSE-S3) 進行伺服器端加密](UsingServerSideEncryption.md)。
      + 若要使用儲存在 AWS Key Management Service () 中的金鑰來加密上傳的檔案AWS KMS，請選擇**AWS Key Management Service 金鑰 (SSE-KMS)**。然後針對 **AWS KMS 金鑰**，選擇下列其中一個選項：
        + 若要從可用的 KMS 金鑰清單中選擇，請選擇**從 AWS KMS keys中選擇**，然後從可用金鑰清單中選擇您的 **KMS 金鑰**。

           AWS 受管金鑰 (`aws/s3`) 和您的客戶受管金鑰都會顯示在此清單中。如需詳細了解客戶受管金鑰，請參閱《AWS Key Management Service 開發人員指南》**中的[客戶金鑰和 AWS 金鑰](https://docs.aws.amazon.com//kms/latest/developerguide/concepts.html#key-mgmt)。
        + 若要輸入 KMS 金鑰 ARN，請選擇**輸入 AWS KMS key ARN**，然後在出現的欄位中輸入您的 KMS 金鑰 ARN。
        + 若要在 AWS KMS 主控台中建立新的客戶受管金鑰，請選擇**建立 KMS 金鑰**。

          如需建立 的詳細資訊 AWS KMS key，請參閱《 *AWS Key Management Service 開發人員指南*》中的[建立金鑰](https://docs.aws.amazon.com//kms/latest/developerguide/create-keys.html)。
**重要**  
您只能使用 AWS 區域 與儲存貯體相同的 KMS 金鑰。Amazon S3 主控台僅會列出與儲存貯體位於相同區域的前 100 個 KMS 金鑰。若要使用未列出的 KMS 金鑰，必須輸入 KMS 金鑰 ARN。若您想要使用其他帳戶的 KMS 金鑰，您必須先具有該金鑰的使用權限，然後輸入 KMS 金鑰 ARN。  
Amazon S3 僅支援對稱加密 KMS 金鑰，而不支援非對稱 KMS 金鑰。如需詳細資訊，請參閱《AWS Key Management Service 開發人員指南》**中的[識別對稱和非對稱 KMS 金鑰](https://docs.aws.amazon.com//kms/latest/developerguide/find-symm-asymm.html)。

1. 若要使用額外的檢查總和，請選擇 **On** (開啟)。然後為 **檢查總和函數**，選擇您要使用的函數。Amazon S3 在接收完整物件後計算並存儲檢查總和的值。您可以使用 **預先計算的值** 方塊以提供預先計算的值。如果您這樣做，Amazon S3 會將您提供的值與其計算的值進行比較。如果兩個值不匹配，Amazon S3 將產生錯誤。

   通過額外的檢查總和，您可以指定要用於驗證資料的檢查總合演算法。如需額外的檢查總和詳細資訊，請參閱「[在 Amazon S3 中檢查物件完整性](checking-object-integrity.md)」。

1. 若要將標籤新增至您要上傳的所有物件，請選擇 **Add tag** (新增標籤)。在**金鑰**欄位中輸入標籤名稱。輸入標籤值。

   物件標記提供您一個分類儲存的方法。每個標籤都是金鑰值對。金鑰與標記值皆區分大小寫。每物件最多可有 10 個標籤。標籤金鑰最長可包含 128 個 Unicode 字元；標籤值最長可包含 255 個 Unicode 字元。如需物件標籤的詳細資訊，請參閱 [使用標籤為物件分類](object-tagging.md)。

1. 若要新增中繼資料，請選擇 **Add metadata** (新增中繼資料)。

   1. 在 **Type** (類型) 下，選擇 **System defined** (系統定義) 或 **User defined** (使用者定義)。

      對於系統定義的中繼資料，您可以選取常見的 HTTP 標頭，例如 **Content-Type** 和 **Content-Disposition**。如需系統定義的中繼資料清單及是否可新增值的資訊，請參閱「[系統定義的物件中繼資料](UsingMetadata.md#SysMetadata)」。以字首 `x-amz-meta-` 開頭的所有中繼資料都會視為使用者定義的中繼資料。使用者定義的中繼資料會與 物件一起存放，並在下載物件時傳回。金鑰及其值都必須符合 US-ASCII 標準。使用者定義的中繼資料最大可達 2 KB。如需系統定義與使用者定義中繼資料的詳細資訊，請參閱 「[使用物件中繼資料](UsingMetadata.md)」。

   1. 針對 **Key** (金鑰) 中，選擇一個金鑰。

   1. 輸入金鑰的值。

1. 若要上傳物件，請選擇 **Upload** (上傳)。

   Amazon S3 會上傳您的物件。上傳完成後，您可以在 **Upload: status** (上傳：狀態) 頁面上看到成功訊息。

1. 選擇 **Exit (退出)**。

### 使用 AWS CLI
<a name="UploadObjSingleOpCLI"></a>

您可以傳送 `PUT` 請求，以便在單一操作中上傳多達 5 GB 的物件。如需詳細資訊，請參閱《AWS CLI 命令參考》**中的 [https://docs.aws.amazon.com/cli/latest/reference/s3api/put-object.html#examples](https://docs.aws.amazon.com/cli/latest/reference/s3api/put-object.html#examples) 範例。

### 使用 REST API
<a name="UploadObjSingleOpREST"></a>

您可以傳送 REST 請求以上傳物件。您可以傳送 `PUT` 請求，以單一操作上傳資料。如需詳細資訊，請參閱 [PUT 物件](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html)。

### 使用 AWS SDKs
<a name="UploadInSingleOp"></a>

如需如何使用 AWS SDKs 上傳物件的範例，請參閱《*Amazon Simple Storage Service API 參考*》中的[程式碼範例](https://docs.aws.amazon.com/AmazonS3/latest/API/s3_example_s3_PutObject_section.html)。

如需使用 AWS SDKs的一般資訊，請參閱《[Amazon Simple Storage Service API 參考》中的使用 SDK 與 Amazon S3 一起開發 AWS SDKs](https://docs.aws.amazon.com/AmazonS3/latest/API/sdk-general-information-section.html)。 **

## 防止上傳具有相同金鑰名稱的物件
<a name="upload-objects-with-same-key-name"></a>

您可以在上傳操作時使用條件式寫入，在建立物件之前，檢查物件是否已存在於您的儲存貯體中。這可以防止覆寫現有資料。條件式寫入會在上傳時，驗證您的儲存貯體中不存在具有相同金鑰名稱的現有物件。

您可以針對 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) 或 [CompleteMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html) 請求使用條件式寫入。

如需條件式請求的詳細資訊，請參閱[使用條件式請求將先決條件新增至 S3 操作](conditional-requests.md)。

# 在 Amazon S3 中使用分段上傳來上傳和複製物件
<a name="mpuoverview"></a>

您可利用分段上傳，將單一物件以一組組件上傳至 Amazon S3。每個組件都是物件資料的接續部分。您可依任何順序分別上傳這些物件組件。對於上傳，您更新的 AWS 用戶端會自動計算物件的檢查總和，並將其連同物件大小一起傳送至 Amazon S3，做為請求的一部分。若任何組件的傳輸失敗，您可再次傳輸該組件，而不會影響其他組件。當物件的所有組件都上傳完後，Amazon S3 會將這些組件組合起來建立該物件。最佳實務是針對 100 MB 或更大的物件使用分段上傳，而不是以單一操作進行上傳。

使用分段上傳具備下列優勢：
+ **改善輸送量** - 您可平行上傳各組件以改進輸送量。
+ **快速從任何網路問題復原** - 組件大小若較小，對於重新開始因為網路發生錯誤而上傳失敗的影響可降到最低。
+ **暫停及繼續上傳物件** - 您可在一段時間內上傳物件組件。啟動分段上傳之後就不會過期；您必須明確地完成或中止分段上傳。
+ **在您知道最終物件大小前開始上傳** - 您可在建立物件的同時上傳物件。

建議您依照下列方式使用分段上傳：
+ 如果您透過穩定的高頻寬網路上傳大型物件，使用分段上傳可同時上傳多個物件組件以取得多執行緒效能，因而充分利用可用的頻寬。
+ 如果您透過不穩定的網路進行上傳，使用分段上傳可避免上傳重新開始，因而更快從網路錯誤中復原。使用分段上傳時，只有上傳期間遭到中斷的組件才需要重試上傳。您不需要從頭開始重新上傳物件。

**注意**  
如需將 Amazon S3 Express One Zone 儲存類別與目錄儲存貯體搭配使用的詳細資訊，請參閱 [S3 Express One Zone](directory-bucket-high-performance.md#s3-express-one-zone) 和 [使用目錄儲存貯體](directory-buckets-overview.md)。如需使用分段上傳搭配 S3 Express One Zone 和目錄儲存貯體的詳細資訊，請參閱 [搭配目錄儲存貯體使用分段上傳](s3-express-using-multipart-upload.md)。

## 分段上傳程序
<a name="mpu-process"></a>

分段上傳是三步驟的程序：啟動上傳、上傳物件的各組件，以及在上傳完所有組件後，完成分段上傳。Amazon S3 一收到完成分段上傳請求，就會從上傳的組件建構物件，然後您即可像存取儲存貯體中的任何其他物件一樣存取該物件。

您可以列出所有進行中的分段上傳，或是取得特定分段上傳之已上傳組件的清單。本節會一一說明這些操作。

**啟動分段上傳**  
當您傳送啟動分段上傳的請求時，請務必指定檢查總和類型。然後，Amazon S3 會傳回包含上傳 ID 的回應，這是分段上傳的唯一識別碼。當您上傳組件、列出組件、完成上傳或停止上傳時，都需要此上傳 ID。如果您想要提供中繼資料來描述正在上傳的物件，則必須在啟動分段上傳的請求中提供。匿名使用者無法啟動分段上傳。

**組件上傳**  
上傳組件時，除了上傳 ID 之外，還必須指定組件編號。您可選擇 1 到 10,000 之間的任何組件編號。組件編號可找出獨特的某個組件，以及其在上傳中物件內的位置。您選擇的組件編號無須為連續的號碼 (例如，其可為 1、5 和 14)。請注意，如果您使用與先前上傳組件相同的組件編號上傳新組件，則會覆寫先前上傳的組件。

當您上傳組件時，Amazon S3 會傳回檢查總和演算法類型，並以每個組件的檢查總和值作為回應中的標頭。您必須記錄每個上傳組件的組件編號與 ETag 值。後續的要求中必須包含這些值，才能完成分段上傳。每個組件在上傳時都會有自己的 ETag。不過，分段上傳完成並合併所有組件之後，所有組件會屬於一個 ETag，作為多個檢查總和的檢查總和。

**重要**  
在您啟動分段上傳及上傳一或多個組件之後，您必須完成或停止分段上傳，才能停止產生儲存已上傳組件的費用。只有在您完成或停止分段上傳「之後」**，Amazon S3 才會釋出組件儲存空間，並停止向您收取儲存組件的費用。  
停止分段上傳之後，即無法再次使用該上傳 ID 上傳任何組件。如有組件正在進行上傳，即使在您停止上傳之後，這些上傳仍有可能成功或失敗。若要確保釋出所有組件耗用的所有儲存空間，您必須等到所有組件上傳完成，再停止分段上傳。

**完成分段上傳**  
當您完成分段上傳時，Amazon S3 會根據組件編號以遞增順序串連各個組件，建立物件。*啟動分段上傳*要求中若已提供任何物件中繼資料，Amazon S3 就會建立該中繼資料與物件之間的關聯性。成功*完成*請求之後，這些片段就不再存在。

您的「完成分段上傳」**請求必須包含上傳 ID，以及組件編號和其對應 ETag 值的清單。Amazon S3 回應包含的 ETag 可識別獨特的物件資料組合。這個 ETag 不一定是物件數據的 MD5 雜湊。

當您在分段上傳期間提供完整的物件檢查總和時， AWS 開發套件會將檢查總和傳遞給 Amazon S3，S3 會驗證物件完整性伺服器端，並將其與接收的值進行比較。如果值相符，則 S3 會儲存物件。如果這兩個值不相符，Amazon S3 的請求會失敗並顯示 `BadDigest` 錯誤。物件的檢查總和也會儲存在物件中繼資料內，以供稍後用來驗證物件的資料完整性。

**分段上傳呼叫範例**  
 在此範例中，假設您正在為 100 GB 的檔案產生分段上傳。在此情況下，您會為整個程序執行以下 API 呼叫。總共會有 1,002 個 API 呼叫。
+ 一個 `[CreateMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html)` 呼叫以啟動此程序。
+ 1,000 個 `[UploadPart](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html)` 呼叫，每個會上傳 100 MB 的組件，總大小為 100 GB。
+ 一個完成程序的 `[CompleteMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html)` 呼叫。

**分段上傳清單**  
您可列出特定分段上傳的組件或所有進行中之分段上傳。列出組件操作會傳回特定分段上傳之已上傳組件的資訊。Amazon S3 會為每項列出的組件要求，傳回指定分段上傳組件的資訊，上限為 1,000 個組件。如果分段組件上傳中有超過 1,000 個組件，您必須傳送一連串的列出組件請求，才可擷取所有組件。請注意，傳回的組件清單不包含尚未完成之上傳的組件。使用*列出分段上傳*操作，即可取得正在進行中的分段上傳清單。

進行中的分段上傳是您已啟動但尚未完成或已停止的上傳。每個要求最多可傳回 1,000 個分段上傳。若正在進行超過 1,000 個的分段上傳，您必須另行傳送請求以擷取剩餘的分段上傳。傳回的清單僅用於進行驗證。

**重要**  
傳送*完成分段上傳*請求時，請不要使用此清單的結果。而是在上傳 Amazon S3 傳回的組件與相對應之 ETag 值時，保有您自己的組件編號清單。

## 使用分段上傳操作的檢查總和
<a name="mpuchecksums"></a>

當您將物件上傳到 Amazon S3 時，可指定用於 Amazon S3 使用的檢查總和演算法。根據預設， AWS 軟體開發套件和 S3 主控台會針對所有物件上傳使用演算法，您可以覆寫該演算法。如果您使用的是舊版 SDK，且上傳的物件沒有指定的檢查總和，Amazon S3 會自動使用 CRC-64/NVME (`CRC64NVME`) 檢查總和演算法。(這也是有效率地驗證資料完整性的建議選項)。使用 CRC-64/NVME 時，Amazon S3 會在完成分段上傳或一部分上傳之後，計算完整物件的檢查總和。CRC-64/NVME 檢查總和演算法用於計算整個物件的直接檢查總和，或每個組件的檢查總和。

使用分段上傳將物件上傳至 S3 之後，Amazon S3 會計算每一個別部分或完整物件的檢查總和值，並儲存這些值。您可以使用 S3 API 或 AWS SDK，以下列方式擷取檢查總和值：
+ 對於個別組件，您可以使用 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) 或 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.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_PutObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html)。如果您想要執行具有完整物件檢查總和的分段上傳，請指定完整物件檢查總和類型來使用 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload) 和 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload)。若要驗證整個物件的檢查總和值，或是確認在分段上傳中使用的檢查總和類型，請使用 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html)。

**重要**  
如果您搭配**檢查總和**使用分段上傳，則分段上傳中每個上傳部分的零件編號，都必須使用連續的零件編號，並且從 1 開始。使用**檢查總和**時，如果您嘗試使用非連續的組件編號完成分段上傳請求，Amazon S3 會產生 `HTTP 500 Internal Server` 錯誤。

 如需如何搭配分段上傳物件使用檢查總和的詳細資訊，請參閱[在 Amazon S3 中檢查物件完整性](checking-object-integrity.md)。

如需示範如何搭配額外檢查總和使用分段上傳來上傳物件的端對端程序，請參閱[教學課程：透過分段上傳來上傳物件並驗證其資料完整性](tutorial-s3-mpu-additional-checksums.md)。

## 並行分段上傳操作
<a name="distributedmpupload"></a>

在分散式開發環境中，您的應用程式有可能同時對相同的物件啟動數項更新。您的應用程式可能使用相同的物件金鑰，啟動數項分段上傳。然後針對這些每一個上傳，應用程式會上傳各組件，並對 Amazon S3 傳送完成上傳要求，以建立物件。當儲存貯體啟用 S3 版本控制之後，完成分段上傳一律會建立新的版本。當您在已啟用版本控制的儲存貯體中啟動多個使用相同物件金鑰的分段上傳時，物件的目前版本取決於最近開始的上傳 (`createdDate`)。

例如，您可以在上午 10:00 開始對物件提出 `CreateMultipartUpload` 請求。然後，您可以在上午 11:00 對相同的物件提交第二個 `CreateMultipartUpload` 請求。由於第二個請求是最近提交的，因此上午 11:00 的請求所上傳的物件會成為目前版本，即使第一個上傳是在第二個上傳之後完成也一樣。若是未啟用版本控制的儲存貯體，可能會在分段上傳啟動與完成之間收到任何其他請求，這些其他請求可能會先完成。

並行分段上傳請求可能會優先的另一個範例是，如有另一個操作在您使用金鑰啟動分段上傳之後刪除該金鑰。在您完成操作之前，完成分段上傳回應可能會在您甚至未看到物件的情況下，指出物件建立成功。

## 防止在分段上傳期間上傳具有相同金鑰名稱的物件
<a name="multipart-upload-objects-with-same-key-name"></a>

您可以在上傳操作時使用條件式寫入，在建立物件之前，檢查物件是否已存在於您的儲存貯體中。這可以防止覆寫現有資料。條件式寫入會在上傳時，驗證您的儲存貯體中不存在具有相同金鑰名稱的現有物件。

您可以針對 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) 或 [CompleteMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html) 請求使用條件式寫入。

如需條件式請求的詳細資訊，請參閱[使用條件式請求將先決條件新增至 S3 操作](conditional-requests.md)。

## 分段上傳與定價
<a name="mpuploadpricing"></a>

啟動分段上傳之後，Amazon S3 就會保留所有組件，直到您完成或停止上傳為止。在其整個生命週期內，您都要支付此分段上傳及其相關組件的儲存體、頻寬與要求之費用。

這些組件會根據上傳組件時指定的儲存類別計費。不過，如果這些組件上傳至 S3 Glacier Flexible Retrieval 或 S3 Glacier Deep Archive，則不會向您收取這些組件的費用。PUT 請求中正在分段上傳至 S3 Glacier Flexible Retrieval 儲存類別的組件，會按 S3 Glacier Flexible Retrieval 暫存儲存體以 S3 Standard 儲存體費率計費，直到上傳完成為止。此外，`CreateMultipartUpload` 和 `UploadPart` 都會以 S3 Standard 費率計費。只有 `CompleteMultipartUpload` 請求會以 S3 Glacier Flexible Retrieval 費率計費。同樣地，PUT 中正在分段上傳至 S3 Glacier Deep Archive 儲存類別的組件，會按 S3 Glacier Flexible Retrieval 暫存儲存體以 S3 Standard 儲存體費率計費，直到上傳完成為止。只有 `CompleteMultipartUpload` 請求會以 S3 Glacier Deep Archive 費率計費。

如果停止分段上傳，Amazon S3 會刪除上傳成品及所有已上傳的組件。您無須支付這些成品的費用。無論指定的儲存空間類別為何，刪除不完整的分段上傳都不會收取提前刪除費用。如需定價的詳細資訊，請參閱 [Amazon S3 定價](https://aws.amazon.com/s3/pricing/)。

**注意**  
為了將儲存費用降至最低，建議您使用 `AbortIncompleteMultipartUpload` 動作，將生命週期規則設定為在指定天數後刪除不完整的分段上傳。如需詳細了解生命週期規則的建立，以刪除不完整分段上傳，請參閱[設定儲存貯體生命週期組態，刪除不完整分段上傳](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpu-abort-incomplete-mpu-lifecycle-config.html)。

## 分段上傳的 API 支援
<a name="apisupportformpu"></a>

Amazon Simple Storage Service API 參考**中的下列章節說明了分段上傳的 REST API。

如需使用 AWS Lambda 函數的分段上傳逐步解說，請參閱[使用分段上傳和傳輸加速將大型物件上傳至 Amazon S3](https://aws.amazon.com/blogs/compute/uploading-large-objects-to-amazon-s3-using-multipart-upload-and-transfer-acceleration/)。
+ [建立分段上傳](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_UploadPartCopy.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_ListParts.html)
+ [列出分段上傳](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html)

## AWS Command Line Interface 支援分段上傳
<a name="clisupportformpu"></a>

中的下列主題 AWS Command Line Interface 說明分段上傳的操作。
+ [啟動分段上傳](https://docs.aws.amazon.com/cli/latest/reference/s3api/create-multipart-upload.html)
+ [上傳片段](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html)
+ [分段上傳 (複製)](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html)
+ [完成分段上傳](https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html)
+ [中止分段上傳](https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html)
+ [列出組件](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html)
+ [列出分段上傳](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-multipart-uploads.html)

## AWS 支援分段上傳的 SDK
<a name="sdksupportformpu"></a>



您可以使用 AWS SDKs分段上傳物件。如需 API 動作支援的 AWS SDKs 清單，請參閱：
+ [建立分段上傳](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_UploadPartCopy.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_ListParts.html)
+ [列出分段上傳](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html)

## 分段上傳 API 與許可
<a name="mpuAndPermissions"></a>

您必須要有必要許可，才可使用分段上傳操作。您可以使用存取控制清單 (ACL)、儲存貯體政策或使用者政策，為個人授予執行這些操作的許可。下表列出使用 ACL、儲存貯體政策或使用者政策時，各種分段上傳操作所需的許可。


| 動作 | 必要許可 | 
| --- | --- | 
|  建立分段上傳  |  您必須有權對物件執行 `s3:PutObject` 動作，才可建立分段上傳請求。 儲存貯體擁有者可允許其他委託人執行 `s3:PutObject` 動作。  | 
|  啟動分段上傳  |  您必須有權對物件執行 `s3:PutObject` 動作，才可啟動分段上傳。 儲存貯體擁有者可允許其他委託人執行 `s3:PutObject` 動作。  | 
| 啟動者 | 識別分段上傳啟動者的容器元素。如果啟動者是 AWS 帳戶，此元素會提供與擁有者元素相同的資訊。若啟動者是 IAM 使用者，此元素會提供使用者 ARN 與顯示名稱。 | 
| 上傳片段 | 您必須有權對物件執行 `s3:PutObject` 動作，才可分段上傳。 儲存貯體擁有者必須允許啟動者對物件執行 `s3:PutObject` 動作，啟動者才可分段上傳該物件。 | 
| 上傳片段 (複製) | 您必須有權對物件執行 `s3:PutObject` 動作，才可分段上傳。因為您分段上傳現有物件，所以必須要能對來源物件進行 `s3:GetObject`。 啟動者若要分段上傳該物件，儲存貯體擁有者必須允許啟動者對物件執行 `s3:PutObject` 動作。 | 
| 完成分段上傳 | 您必須有權對物件執行 `s3:PutObject` 動作，才可完成分段上傳。 儲存貯體擁有者必須允許啟動者對物件執行 `s3:PutObject` 動作，啟動者才可完成該物件的分段上傳。 | 
| 停止分段上傳 | 您必須有權對物件執行 `s3:AbortMultipartUpload` 動作，才可停止分段上傳。 根據預設，儲存貯體擁有者和分段上傳啟動者可以根據 IAM 和 S3 儲存貯體政策來執行此動作。如果啟動者是 IAM 使用者， AWS 帳戶 則該使用者的 也可以停止該分段上傳。使用 VPC 端點政策，分段上傳的啟動者不會自動獲得執行 `s3:AbortMultipartUpload` 動作的許可。 除了這些預設值之外，儲存貯體擁有者可允許其他委託人對物件執行 `s3:AbortMultipartUpload` 動作。儲存貯體擁有者可拒絕任何委託人執行 `s3:AbortMultipartUpload` 動作。 | 
| 列出組件 | 您必須有權執行 `s3:ListMultipartUploadParts` 動作，才可列出分段上傳的各組件。 儲存貯體擁有者預設具備許可，可對儲存貯體列出任何分段上傳之組件。分段上傳的啟動者則有列出特定分段上傳組件的許可。如果分段上傳啟動器是 IAM 使用者，則 AWS 帳戶 控制該 IAM 使用者的 也具有列出該上傳部分的權限。  除了這些預設值之外，儲存貯體擁有者可允許其他委託人對物件執行 `s3:ListMultipartUploadParts` 動作。儲存貯體擁有者也可拒絕任何委託人執行 `s3:ListMultipartUploadParts` 動作。 | 
| 列出分段上傳 | 您必須有權對儲存貯體執行 `s3:ListBucketMultipartUploads` 動作，才可列出該儲存貯體進行中的分段上傳。 除此預設值外，儲存貯體擁有者可允許其他委託人對儲存貯體執行 `s3:ListBucketMultipartUploads` 動作。 | 
| AWS KMS 加密和解密相關許可 |  若要使用 AWS Key Management Service (AWS KMS) KMS 金鑰透過加密執行分段上傳，申請者必須具有下列許可： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/AmazonS3/latest/userguide/mpuoverview.html)  這些許可是必要的，因為在加密檔案完成分段上傳之前，Amazon S3 必須從部分加密檔案解密並讀取資料。您也需要 `kms:Decrypt` 許可以及使用客戶提供加密金鑰的伺服器端加密，才能取得物件的檢查總和值。如果您在使用 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html) API 時沒有這些必要的許可，則會建立不帶檢查總和值的物件。 如果您的 IAM 使用者或角色與 KMS 金鑰 AWS 帳戶 位於相同位置，請驗證您是否同時擁有金鑰和 IAM 政策的許可。若您的 IAM 使用者或角色屬於與 CMK 不同的帳戶，您必須同時在金鑰政策和您的 IAM 使用者或角色上具備這些許可。  | 
| SSE-C (使用客戶提供加密金鑰的伺服器端加密) | 使用 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html) API 時，您必須提供 SSE-C (使用客戶提供加密金鑰的伺服器端加密)，否則會建立不帶檢查總和的物件，也不會傳回檢查總和值。  | 

如需 ACL 許可與存取原則許可之間關聯性的資訊，請參閱「[ACL 許可與存取政策許可的對應](acl-overview.md#acl-access-policy-permission-mapping)」。如需 IAM 使用者、角色與最佳實務的詳細資訊，請參閱《IAM 使用者指南》**中的 [IAM 身分 (使用者、群組和角色)](https://docs.aws.amazon.com/IAM/latest/UserGuide/id.html)。

## 使用分段上傳操作的檢查總和
<a name="Checksums-mpu-operations"></a>

有三個 Amazon S3 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_CompleteMultipartUpload.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html)。下表指出必須為每個 API 提供的檢查總和標頭和值：


| 檢查總和演算法 | 檢查總和類型 | `CreateMultipartUpload` | `UploadPart` | `CompleteMultipartUpoad` | 
| --- | --- | --- | --- | --- | 
| CRC-64/NVME (`CRC64NVME`) | 完整物件 | 必要標頭：`x-amz-checksum-algorithm` |  選用標頭： `x-amz-checksum-crc64nvme`  |  選用標頭： `x-amz-checksum-algorithm` `x-amz-crc64`  | 
| CRC-32 (`CRC32`) CRC 32-C (`CRC32C`) | 完整物件 |  必要標頭： `x-amz-checksum-algorithm` `x-amz-checksum-type`  |  選用標頭： `x-amz-checksum-crc64nvme`  |  選用標頭： `x-amz-checksum-algorithm` `x-amz-crc32` `x-amz-crc32c`  | 
|  CRC-32 (`CRC32`) CRC-32C (`CRC32C`) SHA-1 (`SHA1`) SHA-256 (`SHA256`) | 複合 |  必要標頭： `x-amz-checksum-algorithm`  |  必要標頭： `x-amz-checksum-crc32` `x-amz-checksum-crc32c` `x-amz-checksum-sha1` `x-amz-checksum-sha256`  |  必要標頭： `CompleteMultiPartUpload` 請求中必須包含所有組件層級檢查總和。 選用標頭： `x-amz-crc32` `x-amz-crc32c` `x-amz-sha1` `x-amz-sha256`  | 

**Topics**
+ [分段上傳程序](#mpu-process)
+ [使用分段上傳操作的檢查總和](#mpuchecksums)
+ [並行分段上傳操作](#distributedmpupload)
+ [防止在分段上傳期間上傳具有相同金鑰名稱的物件](#multipart-upload-objects-with-same-key-name)
+ [分段上傳與定價](#mpuploadpricing)
+ [分段上傳的 API 支援](#apisupportformpu)
+ [AWS Command Line Interface 支援分段上傳](#clisupportformpu)
+ [AWS 支援分段上傳的 SDK](#sdksupportformpu)
+ [分段上傳 API 與許可](#mpuAndPermissions)
+ [使用分段上傳操作的檢查總和](#Checksums-mpu-operations)
+ [設定儲存貯體生命週期組態，以刪除不完整的分段上傳](mpu-abort-incomplete-mpu-lifecycle-config.md)
+ [使用分段上傳來上傳物件](mpu-upload-object.md)
+ [使用高階 .NET TransferUtility 類別上傳目錄](HLuploadDirDotNet.md)
+ [列出分段上傳](list-mpu.md)
+ [使用 AWS SDKs 追蹤分段上傳](track-mpu.md)
+ [中止分段上傳](abort-mpu.md)
+ [使用分段上傳來複製物件](CopyingObjectsMPUapi.md)
+ [教學課程：透過分段上傳來上傳物件並驗證其資料完整性](tutorial-s3-mpu-additional-checksums.md)
+ [Amazon S3 分段上傳限制](qfacts.md)

# 設定儲存貯體生命週期組態，以刪除不完整的分段上傳
<a name="mpu-abort-incomplete-mpu-lifecycle-config"></a>

最佳實務做法建議您使用 `AbortIncompleteMultipartUpload` 動作設定生命週期規則，從而將儲存體費用降至最低。如需中止分段上傳的詳細資訊，請參閱 [中止分段上傳](abort-mpu.md)。

Amazon S3 支援的儲存貯體生命週期規則，可用以指示 Amazon S3 在該過程啟動後指定的天數內，停止尚未完成的分段上傳。當分段上傳未在指定的時間範圍內完成時，其符合中止操作的資格。Amazon S3 接著中止分段上傳，並刪除與該分段上傳相關聯的部分。此規則同時適用於現有的分段上傳和您稍後建立的分段上傳。

 下列生命週期組態範例指定了一項規則，其會採取 `AbortIncompleteMultipartUpload` 動作。

```
<LifecycleConfiguration>
    <Rule>
        <ID>sample-rule</ID>
        <Prefix></Prefix>
        <Status>Enabled</Status>
        <AbortIncompleteMultipartUpload>
          <DaysAfterInitiation>7</DaysAfterInitiation>
        </AbortIncompleteMultipartUpload>
    </Rule>
</LifecycleConfiguration>
```

在此範例中，規則不會針對 `Prefix` 元素指定一值 ([物件金鑰名稱字首](https://docs.aws.amazon.com/general/latest/gr/glos-chap.html#keyprefix))。因此，規則適用於您啟動分段上傳之儲存貯體中的所有物件。任何已啟動且未在七天內完成的分段上傳，都符合中止操作的資格。中止動作對已完成的分段上傳沒有影響。

如需儲存貯體生命週期組態的詳細資訊，請參閱「[管理物件的生命週期](object-lifecycle-mgmt.md)」。

**注意**  
若分段上傳在規則指定的天數內完成，就不會套用 `AbortIncompleteMultipartUpload` 生命週期動作 (也就是說，Amazon S3 不會採取任何動作)。此外，此動作不適用於物件。此生命週期動作不會刪除任何物件。此外，當您移除任何不完整分段上傳時，不會產生 S3 生命週期的提前刪除費用。

## 使用 S3 主控台
<a name="mpu-abort-incomplete-mpu-lifecycle-config-console"></a>

若要自動管理不完整的分段上傳，您可以使用 S3 主控台建立生命週期規則，以在指定天數後，使儲存貯體中未完成的分段上傳位元組過期。下列程序說明如何新增生命週期規則，以在 7 天後刪除未完成的分段上傳。如需新增生命週期規則的詳細資訊，請參閱 [設定儲存貯體的 S3 生命週期組態](how-to-set-lifecycle-configuration-intro.md)。

**新增生命週期規則以中止超過 7 天未完成的分段上傳**

1. 登入 AWS 管理主控台 並開啟位於 https：//[https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/) 的 Amazon S3 主控台。

1. 在 **Buckets (儲存貯體)** 清單中，選擇要建立生命週期規則的儲存貯體名稱。

1. 選擇 **Management (管理)** 標籤，然後選擇 **Create lifecycle rule (建立生命週期規則)**。

1. 在 **Lifecycle rule name (生命週期規則名稱)** 中，輸入規則的名稱。

   在儲存貯體內，名稱必須是唯一的。

1. 選擇生命週期規則的範圍：
   + 若要針對具有特定字首的所有物件建立生命週期規則，請選擇 **Limit the scope of this rule using one or more filters** (使用一或多個篩選條件限制此規則的範圍)，然後在 **Prefix** (字首) 欄位中輸入字首。
   + 若要針對儲存貯體中的所有物件建立生命週期規則，請選擇 **This rule applies to **all** objects in the bucket** (此規則適用於儲存貯體中的所有物件)，然後選擇 **I acknowledge that this rule applies to all objects in the bucket** (我確認此規則適用於儲存貯體中的所有物件)。

1. 在 **Lifecycle rule actions** (生命週期規則動作) 下，選取 **Delete expired object delete markers or incomplete multipart uploads** (刪除過期物件標記或未完成的分段上傳)。

1. 在 **Delete expired delete markers or incomplete multipart uploads** (刪除過期刪除標記或未完成的分段上傳) 下，選擇 **Delete incomplete multipart uploads** (刪除未完成的分段上傳)。

1. 在 **Number of days** (天數) 欄位中，輸入要刪除幾天後未完成的分段上傳 (在此範例中，7 天)。

1. 選擇**建立規則**。

## 使用 AWS CLI
<a name="mpu-abort-incomplete-mpu-lifecycle-config-cli"></a>

下列`put-bucket-lifecycle-configuration` AWS Command Line Interface (AWS CLI) 命令會新增指定儲存貯體的生命週期組態。若要使用此命令，請以您的資訊取代 `user input placeholders`。

```
aws s3api put-bucket-lifecycle-configuration  \
        --bucket amzn-s3-demo-bucket  \
        --lifecycle-configuration filename-containing-lifecycle-configuration
```

下列範例說明如何新增生命週期規則，以使用 AWS CLI中止未完成的分段上傳。其中包含範例 JSON 生命週期組態，以中止超過 7 天未完成的分段上傳。

若要在此範例中使用 CLI 命令，請以您的資訊取代 `user input placeholders`。

**新增生命週期規則以中止未完成的分段上傳**

1. 設定 AWS CLI。如需說明，請參閱《[Amazon S3 API 參考》中的使用 AWS CLI 使用](https://docs.aws.amazon.com/AmazonS3/latest/API/setup-aws-cli.html) Amazon S3 開發。 *Amazon S3 * 

1. 將以下範例生命週期組態儲存至檔案 (例如，*`lifecycle.json`*``)。此範例組態指定了空的字首，因此其會套用至該儲存貯體中的所有物件。若要將組態限制為物件子集，您可以指定字首。

   ```
   {
       "Rules": [
           {
               "ID": "Test Rule",
               "Status": "Enabled",
               "Filter": {
                   "Prefix": ""
               },
               "AbortIncompleteMultipartUpload": {
                   "DaysAfterInitiation": 7
               }
           }
       ]
   }
   ```

1.  執行下列 CLI 命令，以在您的儲存貯體上設定此生命週期組態。

   ```
   aws s3api put-bucket-lifecycle-configuration   \
   --bucket amzn-s3-demo-bucket  \
   --lifecycle-configuration file://lifecycle.json
   ```

1.  若要驗證是否已在您的儲存貯體上設定生命週期組態，請使用下列 `get-bucket-lifecycle` 命令擷取生命週期組態。

   ```
   aws s3api get-bucket-lifecycle  \
   --bucket amzn-s3-demo-bucket
   ```

1.  若要刪除生命週期組態，請如下使用 `delete-bucket-lifecycle` 命令。

   ```
   aws s3api delete-bucket-lifecycle \
   --bucket amzn-s3-demo-bucket
   ```

# 使用分段上傳來上傳物件
<a name="mpu-upload-object"></a>

您可以使用分段上傳，以程式設計方式將單一物件上傳到 Amazon S3。每個物件都會以一組組件上傳。每個組件都是物件資料的接續部分。您可依任何順序分別上傳這些物件組件。若任何組件的傳輸失敗，您可再次傳輸該組件，而不會影響其他組件。當物件的所有組件都全部上傳完後，Amazon S3 會將這些組件組合起來建立該物件。匿名使用者無法啟動分段上傳。

如需搭配額外檢查總和使用分段上傳來上傳物件的端對端程序，請參閱[教學課程：透過分段上傳來上傳物件並驗證其資料完整性](tutorial-s3-mpu-additional-checksums.md)。

下一節說明如何搭配 AWS Command Line Interface和 AWS SDKs 使用分段上傳。

## 使用 S3 主控台
<a name="MultipartUploadConsole"></a>

您可以將任何檔案類型 (影像、備份、資料、影片等) 上傳至 S3 儲存貯體。使用 Amazon S3 主控台可上傳的檔案大小上限為 160 GB。若要上傳大於 160 GB 的檔案，請使用 AWS Command Line Interface (AWS CLI)、 AWS SDKs或 Amazon S3 REST API。

如需透過 上傳物件的說明 AWS 管理主控台，請參閱 [上傳物件](upload-objects.md)。

## 使用 AWS CLI
<a name="UsingCLImpUpload"></a>

以下描述使用 AWS CLI進行分段上傳的 Amazon S3 操作。
+ [啟動分段上傳](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/create-multipart-upload.html)
+ [上傳片段](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html)
+ [分段上傳 (複製)](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html)
+ [完成分段上傳](https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html)
+ [中止分段上傳](https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html)
+ [列出組件](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html)
+ [列出分段上傳](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-multipart-uploads.html)

## 使用 REST API
<a name="UsingRESTAPImpUpload"></a>

《*Amazon Simple Storage Service API 參考*》中的下列章節說明了分段上傳的 REST API。
+ [啟動分段上傳](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadInitiate.html)
+ [上傳片段](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadUploadPart.html)
+ [完成分段上傳](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadComplete.html)
+ [停止分段上傳](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadAbort.html)
+ [列出組件](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadListParts.html)
+ [列出分段上傳](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadListMPUpload.html)

## 使用 AWS SDKs（高階 API)
<a name="multipart-upload-high-level"></a>

 AWS SDKs公開了高階 API，可將完成分段上傳所需的不同 API 操作合併為單一操作，以簡化分段上傳。如需詳細資訊，請參閱[在 Amazon S3 中使用分段上傳來上傳和複製物件](mpuoverview.md)。

當您需要暫停再繼續進行分段上傳、在上傳期間改變組件大小或事先不知道資料大小時，請使用低階 API 方法。以低階 API 方法進行分段上傳提供其他功能。如需詳細資訊，請參閱[使用 AWS SDKs（低階 API)](#mpu-upload-low-level)。

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

如需如何使用適用於 Java 的 AWS SDK 執行分段上傳的範例，請參閱《[Amazon S3 API 參考》中的使用 AWS SDK 上傳或下載大型檔案往返](https://docs.aws.amazon.com/AmazonS3/latest/API/s3_example_s3_Scenario_UsingLargeFiles_section.html) Amazon S3。 *Amazon S3 *

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

若要上傳檔案到 S3 儲存貯體，可使用 `TransferUtility` 類別。當從檔案上傳資料時，您必須提供物件的金鑰名稱。如果不提供的話，API 使用檔案名稱作為金鑰。當從串流上傳資料時，您必須提供物件的金鑰名稱。

若要設定進階上傳選項 (如片段大小、同時上傳多個片段時的執行緒數、中繼資料、儲存方案或 ACL)，請使用 `TransferUtilityUploadRequest` 類別。

**注意**  
在您使用資料來源的串流時，`TransferUtility` 類別不會執行並行上傳。

下列 C\$1 範例會將檔案分成多個部分 (組件)，上傳至 Amazon S3 儲存貯體。此顯示如何使用不同的 `TransferUtility.Upload` 多載上傳檔案。每個後續的呼叫都會上傳取代前一個上傳。如需有關設定和執行程式碼範例的資訊，請參閱《[適用於 .NET 的 AWS SDK 開發人員指南》中的適用於 .NET 的 SDK 入門](https://docs.aws.amazon.com/sdk-for-net/latest/developer-guide/net-dg-setup.html)。 *AWS *

```
using Amazon;
using Amazon.S3;
using Amazon.S3.Transfer;
using System;
using System.IO;
using System.Threading.Tasks;

namespace Amazon.DocSamples.S3
{
    class UploadFileMPUHighLevelAPITest
    {
        private const string bucketName = "*** provide bucket name ***";
        private const string keyName = "*** provide a name for the uploaded object ***";
        private const string filePath = "*** provide the full path name of the file to upload ***";
        // Specify your bucket region (an example region is shown).
        private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2;
        private static IAmazonS3 s3Client;

        public static void Main()
        {
            s3Client = new AmazonS3Client(bucketRegion);
            UploadFileAsync().Wait();
        }

        private static async Task UploadFileAsync()
        {
            try
            {
                var fileTransferUtility =
                    new TransferUtility(s3Client);

                // Option 1. Upload a file. The file name is used as the object key name.
                await fileTransferUtility.UploadAsync(filePath, bucketName);
                Console.WriteLine("Upload 1 completed");

                // Option 2. Specify object key name explicitly.
                await fileTransferUtility.UploadAsync(filePath, bucketName, keyName);
                Console.WriteLine("Upload 2 completed");

                // Option 3. Upload data from a type of System.IO.Stream.
                using (var fileToUpload = 
                    new FileStream(filePath, FileMode.Open, FileAccess.Read))
                {
                    await fileTransferUtility.UploadAsync(fileToUpload,
                                               bucketName, keyName);
                }
                Console.WriteLine("Upload 3 completed");

                // Option 4. Specify advanced settings.
                var fileTransferUtilityRequest = new TransferUtilityUploadRequest
                {
                    BucketName = bucketName,
                    FilePath = filePath,
                    StorageClass = S3StorageClass.StandardInfrequentAccess,
                    PartSize = 6291456, // 6 MB.
                    Key = keyName,
                    CannedACL = S3CannedACL.PublicRead
                };
                fileTransferUtilityRequest.Metadata.Add("param1", "Value1");
                fileTransferUtilityRequest.Metadata.Add("param2", "Value2");

                await fileTransferUtility.UploadAsync(fileTransferUtilityRequest);
                Console.WriteLine("Upload 4 completed");
            }
            catch (AmazonS3Exception e)
            {
                Console.WriteLine("Error encountered on server. Message:'{0}' when writing an object", e.Message);
            }
            catch (Exception e)
            {
                Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message);
            }

        }
    }
}
```

------
#### [ JavaScript ]

**Example**  
上傳大型檔案。  

```
import { S3Client } from "@aws-sdk/client-s3";
import { Upload } from "@aws-sdk/lib-storage";

import {
  ProgressBar,
  logger,
} from "@aws-doc-sdk-examples/lib/utils/util-log.js";

const twentyFiveMB = 25 * 1024 * 1024;

export const createString = (size = twentyFiveMB) => {
  return "x".repeat(size);
};

/**
 * Create a 25MB file and upload it in parts to the specified
 * Amazon S3 bucket.
 * @param {{ bucketName: string, key: string }}
 */
export const main = async ({ bucketName, key }) => {
  const str = createString();
  const buffer = Buffer.from(str, "utf8");
  const progressBar = new ProgressBar({
    description: `Uploading "${key}" to "${bucketName}"`,
    barLength: 30,
  });

  try {
    const upload = new Upload({
      client: new S3Client({}),
      params: {
        Bucket: bucketName,
        Key: key,
        Body: buffer,
      },
    });

    upload.on("httpUploadProgress", ({ loaded, total }) => {
      progressBar.update({ current: loaded, total });
    });

    await upload.done();
  } catch (caught) {
    if (caught instanceof Error && caught.name === "AbortError") {
      logger.error(`Multipart upload was aborted. ${caught.message}`);
    } else {
      throw caught;
    }
  }
};
```

**Example**  
下載大型檔案。  

```
import { fileURLToPath } from "node:url";
import { GetObjectCommand, NoSuchKey, S3Client } from "@aws-sdk/client-s3";
import { createWriteStream, rmSync } from "node:fs";

const s3Client = new S3Client({});
const oneMB = 1024 * 1024;

export const getObjectRange = ({ bucket, key, start, end }) => {
  const command = new GetObjectCommand({
    Bucket: bucket,
    Key: key,
    Range: `bytes=${start}-${end}`,
  });

  return s3Client.send(command);
};

/**
 * @param {string | undefined} contentRange
 */
export const getRangeAndLength = (contentRange) => {
  const [range, length] = contentRange.split("/");
  const [start, end] = range.split("-");
  return {
    start: Number.parseInt(start),
    end: Number.parseInt(end),
    length: Number.parseInt(length),
  };
};

export const isComplete = ({ end, length }) => end === length - 1;

const downloadInChunks = async ({ bucket, key }) => {
  const writeStream = createWriteStream(
    fileURLToPath(new URL(`./${key}`, import.meta.url)),
  ).on("error", (err) => console.error(err));

  let rangeAndLength = { start: -1, end: -1, length: -1 };

  while (!isComplete(rangeAndLength)) {
    const { end } = rangeAndLength;
    const nextRange = { start: end + 1, end: end + oneMB };

    const { ContentRange, Body } = await getObjectRange({
      bucket,
      key,
      ...nextRange,
    });
    console.log(`Downloaded bytes ${nextRange.start} to ${nextRange.end}`);

    writeStream.write(await Body.transformToByteArray());
    rangeAndLength = getRangeAndLength(ContentRange);
  }
};

/**
 * Download a large object from and Amazon S3 bucket.
 *
 * When downloading a large file, you might want to break it down into
 * smaller pieces. Amazon S3 accepts a Range header to specify the start
 * and end of the byte range to be downloaded.
 *
 * @param {{ bucketName: string, key: string }}
 */
export const main = async ({ bucketName, key }) => {
  try {
    await downloadInChunks({
      bucket: bucketName,
      key: key,
    });
  } catch (caught) {
    if (caught instanceof NoSuchKey) {
      console.error(`Failed to download object. No such key "${key}".`);
      rmSync(key);
    }
  }
};
```

------
#### [ Go ]

如需分段上傳的 Go 程式碼範例的詳細資訊，請參閱[使用 AWS SDK 在 Amazon S3 之間上傳或下載大型檔案](https://docs.aws.amazon.com/AmazonS3/latest/API/s3_example_s3_Scenario_UsingLargeFiles_section.html)。

**Example**  
使用上傳管理員將資料分成多個部分，並同時上傳它們來上傳大型物件。  

```
import (
	"bytes"
	"context"
	"errors"
	"fmt"
	"io"
	"log"
	"os"
	"time"

	"github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/feature/s3/manager"
	"github.com/aws/aws-sdk-go-v2/service/s3"
	"github.com/aws/aws-sdk-go-v2/service/s3/types"
	"github.com/aws/smithy-go"
)

// BucketBasics encapsulates the Amazon Simple Storage Service (Amazon S3) actions
// used in the examples.
// It contains S3Client, an Amazon S3 service client that is used to perform bucket
// and object actions.
type BucketBasics struct {
	S3Client *s3.Client
}
```

```
// UploadLargeObject uses an upload manager to upload data to an object in a bucket.
// The upload manager breaks large data into parts and uploads the parts concurrently.
func (basics BucketBasics) UploadLargeObject(ctx context.Context, bucketName string, objectKey string, largeObject []byte) error {
	largeBuffer := bytes.NewReader(largeObject)
	var partMiBs int64 = 10
	uploader := manager.NewUploader(basics.S3Client, func(u *manager.Uploader) {
		u.PartSize = partMiBs * 1024 * 1024
	})
	_, err := uploader.Upload(ctx, &s3.PutObjectInput{
		Bucket: aws.String(bucketName),
		Key:    aws.String(objectKey),
		Body:   largeBuffer,
	})
	if err != nil {
		var apiErr smithy.APIError
		if errors.As(err, &apiErr) && apiErr.ErrorCode() == "EntityTooLarge" {
			log.Printf("Error while uploading object to %s. The object is too large.\n"+
				"The maximum size for a multipart upload is 5TB.", bucketName)
		} else {
			log.Printf("Couldn't upload large object to %v:%v. Here's why: %v\n",
				bucketName, objectKey, err)
		}
	} else {
		err = s3.NewObjectExistsWaiter(basics.S3Client).Wait(
			ctx, &s3.HeadObjectInput{Bucket: aws.String(bucketName), Key: aws.String(objectKey)}, time.Minute)
		if err != nil {
			log.Printf("Failed attempt to wait for object %s to exist.\n", objectKey)
		}
	}

	return err
}
```

**Example**  
使用下載管理員分段取得資料並同時下載它們來下載大型物件。  

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

------
#### [ PHP ]

本主題說明如何從 使用高階`Aws\S3\Model\MultipartUpload\UploadBuilder`類別 適用於 PHP 的 AWS SDK 進行分段檔案上傳。如需適用於 Ruby 的 AWS SDK API 的詳細資訊，請前往[AWS 適用於 Ruby 的 SDK - 第 2 版](https://docs.aws.amazon.com/sdkforruby/api/index.html)。

下列 PHP 範例會將檔案上傳至 Amazon S3 儲存貯體。本範例會示範如何設定 `MultipartUploader` 物件的參數。

```
 require 'vendor/autoload.php';

use Aws\Exception\MultipartUploadException;
use Aws\S3\MultipartUploader;
use Aws\S3\S3Client;

$bucket = '*** Your Bucket Name ***';
$keyname = '*** Your Object Key ***';

$s3 = new S3Client([
    'version' => 'latest',
    'region'  => 'us-east-1'
]);

// Prepare the upload parameters.
$uploader = new MultipartUploader($s3, '/path/to/large/file.zip', [
    'bucket' => $bucket,
    'key'    => $keyname
]);

// Perform the upload.
try {
    $result = $uploader->upload();
    echo "Upload complete: {$result['ObjectURL']}" . PHP_EOL;
} catch (MultipartUploadException $e) {
    echo $e->getMessage() . PHP_EOL;
}
```

------
#### [ Python ]

下列範例會使用高階分段上傳 Python API (`TransferManager` 類別) 載入物件。

```
import sys
import threading

import boto3
from boto3.s3.transfer import TransferConfig


MB = 1024 * 1024
s3 = boto3.resource("s3")


class TransferCallback:
    """
    Handle callbacks from the transfer manager.

    The transfer manager periodically calls the __call__ method throughout
    the upload and download process so that it can take action, such as
    displaying progress to the user and collecting data about the transfer.
    """

    def __init__(self, target_size):
        self._target_size = target_size
        self._total_transferred = 0
        self._lock = threading.Lock()
        self.thread_info = {}

    def __call__(self, bytes_transferred):
        """
        The callback method that is called by the transfer manager.

        Display progress during file transfer and collect per-thread transfer
        data. This method can be called by multiple threads, so shared instance
        data is protected by a thread lock.
        """
        thread = threading.current_thread()
        with self._lock:
            self._total_transferred += bytes_transferred
            if thread.ident not in self.thread_info.keys():
                self.thread_info[thread.ident] = bytes_transferred
            else:
                self.thread_info[thread.ident] += bytes_transferred

            target = self._target_size * MB
            sys.stdout.write(
                f"\r{self._total_transferred} of {target} transferred "
                f"({(self._total_transferred / target) * 100:.2f}%)."
            )
            sys.stdout.flush()


def upload_with_default_configuration(
    local_file_path, bucket_name, object_key, file_size_mb
):
    """
    Upload a file from a local folder to an Amazon S3 bucket, using the default
    configuration.
    """
    transfer_callback = TransferCallback(file_size_mb)
    s3.Bucket(bucket_name).upload_file(
        local_file_path, object_key, Callback=transfer_callback
    )
    return transfer_callback.thread_info


def upload_with_chunksize_and_meta(
    local_file_path, bucket_name, object_key, file_size_mb, metadata=None
):
    """
    Upload a file from a local folder to an Amazon S3 bucket, setting a
    multipart chunk size and adding metadata to the Amazon S3 object.

    The multipart chunk size controls the size of the chunks of data that are
    sent in the request. A smaller chunk size typically results in the transfer
    manager using more threads for the upload.

    The metadata is a set of key-value pairs that are stored with the object
    in Amazon S3.
    """
    transfer_callback = TransferCallback(file_size_mb)

    config = TransferConfig(multipart_chunksize=1 * MB)
    extra_args = {"Metadata": metadata} if metadata else None
    s3.Bucket(bucket_name).upload_file(
        local_file_path,
        object_key,
        Config=config,
        ExtraArgs=extra_args,
        Callback=transfer_callback,
    )
    return transfer_callback.thread_info


def upload_with_high_threshold(local_file_path, bucket_name, object_key, file_size_mb):
    """
    Upload a file from a local folder to an Amazon S3 bucket, setting a
    multipart threshold larger than the size of the file.

    Setting a multipart threshold larger than the size of the file results
    in the transfer manager sending the file as a standard upload instead of
    a multipart upload.
    """
    transfer_callback = TransferCallback(file_size_mb)
    config = TransferConfig(multipart_threshold=file_size_mb * 2 * MB)
    s3.Bucket(bucket_name).upload_file(
        local_file_path, object_key, Config=config, Callback=transfer_callback
    )
    return transfer_callback.thread_info


def upload_with_sse(
    local_file_path, bucket_name, object_key, file_size_mb, sse_key=None
):
    """
    Upload a file from a local folder to an Amazon S3 bucket, adding server-side
    encryption with customer-provided encryption keys to the object.

    When this kind of encryption is specified, Amazon S3 encrypts the object
    at rest and allows downloads only when the expected encryption key is
    provided in the download request.
    """
    transfer_callback = TransferCallback(file_size_mb)
    if sse_key:
        extra_args = {"SSECustomerAlgorithm": "AES256", "SSECustomerKey": sse_key}
    else:
        extra_args = None
    s3.Bucket(bucket_name).upload_file(
        local_file_path, object_key, ExtraArgs=extra_args, Callback=transfer_callback
    )
    return transfer_callback.thread_info


def download_with_default_configuration(
    bucket_name, object_key, download_file_path, file_size_mb
):
    """
    Download a file from an Amazon S3 bucket to a local folder, using the
    default configuration.
    """
    transfer_callback = TransferCallback(file_size_mb)
    s3.Bucket(bucket_name).Object(object_key).download_file(
        download_file_path, Callback=transfer_callback
    )
    return transfer_callback.thread_info


def download_with_single_thread(
    bucket_name, object_key, download_file_path, file_size_mb
):
    """
    Download a file from an Amazon S3 bucket to a local folder, using a
    single thread.
    """
    transfer_callback = TransferCallback(file_size_mb)
    config = TransferConfig(use_threads=False)
    s3.Bucket(bucket_name).Object(object_key).download_file(
        download_file_path, Config=config, Callback=transfer_callback
    )
    return transfer_callback.thread_info


def download_with_high_threshold(
    bucket_name, object_key, download_file_path, file_size_mb
):
    """
    Download a file from an Amazon S3 bucket to a local folder, setting a
    multipart threshold larger than the size of the file.

    Setting a multipart threshold larger than the size of the file results
    in the transfer manager sending the file as a standard download instead
    of a multipart download.
    """
    transfer_callback = TransferCallback(file_size_mb)
    config = TransferConfig(multipart_threshold=file_size_mb * 2 * MB)
    s3.Bucket(bucket_name).Object(object_key).download_file(
        download_file_path, Config=config, Callback=transfer_callback
    )
    return transfer_callback.thread_info


def download_with_sse(
    bucket_name, object_key, download_file_path, file_size_mb, sse_key
):
    """
    Download a file from an Amazon S3 bucket to a local folder, adding a
    customer-provided encryption key to the request.

    When this kind of encryption is specified, Amazon S3 encrypts the object
    at rest and allows downloads only when the expected encryption key is
    provided in the download request.
    """
    transfer_callback = TransferCallback(file_size_mb)

    if sse_key:
        extra_args = {"SSECustomerAlgorithm": "AES256", "SSECustomerKey": sse_key}
    else:
        extra_args = None
    s3.Bucket(bucket_name).Object(object_key).download_file(
        download_file_path, ExtraArgs=extra_args, Callback=transfer_callback
    )
    return transfer_callback.thread_info
```

------

## 使用 AWS SDKs（低階 API)
<a name="mpu-upload-low-level"></a>

 AWS 開發套件公開的低階 API 與分段上傳的 Amazon S3 REST API 非常相似 （請參閱 [在 Amazon S3 中使用分段上傳來上傳和複製物件](mpuoverview.md)。 當您需要暫停和繼續分段上傳、在上傳期間變更組件大小，或事先不知道上傳資料的大小時，請使用低階 API。 當您沒有這些要求時，請使用高階 API （請參閱 [使用 AWS SDKs（高階 API)](#multipart-upload-high-level))。

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

以下範例示範如何使用低階 Java 類別上傳檔案。操作步驟如下：
+ 使用 `AmazonS3Client.initiateMultipartUpload()` 方法，經過 `InitiateMultipartUploadRequest` 物件，開始執行分段上傳。
+ 儲存 `AmazonS3Client.initiateMultipartUpload()` 方法所傳回的上傳 ID。您所提供的上傳 ID，用於後續的每項分段上傳操作。
+ 將物件的部分上傳。請為每一部分，呼叫 `AmazonS3Client.uploadPart()` 方法。您可以在 `UploadPartRequest` 物件中提供部分資訊。
+ 對於每一個部分，將 ETag 儲存在清單 `AmazonS3Client.uploadPart()` 方法的回應中。請您使用 ETag 值完成分段上傳。
+ 呼叫 `AmazonS3Client.completeMultipartUpload()` 方法，完成分段上傳。

**Example**  
如需建立和測試工作範例的說明，請參閱《 適用於 Java 的 AWS SDK 開發人員指南》中的[入門](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/getting-started.html)。  

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class LowLevelMultipartUpload {

    public static void main(String[] args) throws IOException {
        Regions clientRegion = Regions.DEFAULT_REGION;
        String bucketName = "*** Bucket name ***";
        String keyName = "*** Key name ***";
        String filePath = "*** Path to file to upload ***";

        File file = new File(filePath);
        long contentLength = file.length();
        long partSize = 5 * 1024 * 1024; // Set part size to 5 MB.

        try {
            AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                    .withRegion(clientRegion)
                    .withCredentials(new ProfileCredentialsProvider())
                    .build();

            // Create a list of ETag objects. You retrieve ETags for each object part
            // uploaded,
            // then, after each individual part has been uploaded, pass the list of ETags to
            // the request to complete the upload.
            List<PartETag> partETags = new ArrayList<PartETag>();

            // Initiate the multipart upload.
            InitiateMultipartUploadRequest initRequest = new InitiateMultipartUploadRequest(bucketName, keyName);
            InitiateMultipartUploadResult initResponse = s3Client.initiateMultipartUpload(initRequest);

            // Upload the file parts.
            long filePosition = 0;
            for (int i = 1; filePosition < contentLength; i++) {
                // Because the last part could be less than 5 MB, adjust the part size as
                // needed.
                partSize = Math.min(partSize, (contentLength - filePosition));

                // Create the request to upload a part.
                UploadPartRequest uploadRequest = new UploadPartRequest()
                        .withBucketName(bucketName)
                        .withKey(keyName)
                        .withUploadId(initResponse.getUploadId())
                        .withPartNumber(i)
                        .withFileOffset(filePosition)
                        .withFile(file)
                        .withPartSize(partSize);

                // Upload the part and add the response's ETag to our list.
                UploadPartResult uploadResult = s3Client.uploadPart(uploadRequest);
                partETags.add(uploadResult.getPartETag());

                filePosition += partSize;
            }

            // Complete the multipart upload.
            CompleteMultipartUploadRequest compRequest = new CompleteMultipartUploadRequest(bucketName, keyName,
                    initResponse.getUploadId(), partETags);
            s3Client.completeMultipartUpload(compRequest);
        } catch (AmazonServiceException e) {
            // The call was transmitted successfully, but Amazon S3 couldn't process
            // it, so it returned an error response.
            e.printStackTrace();
        } catch (SdkClientException e) {
            // Amazon S3 couldn't be contacted for a response, or the client
            // couldn't parse the response from Amazon S3.
            e.printStackTrace();
        }
    }
}
```

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

下列 C\$1 範例示範如何使用低階 適用於 .NET 的 SDK 分段上傳 API 將檔案上傳至 S3 儲存貯體。如需 Amazon S3 分段上傳的資訊，請參閱 [在 Amazon S3 中使用分段上傳來上傳和複製物件](mpuoverview.md)。

**注意**  
當您使用 適用於 .NET 的 SDK API 上傳大型物件時，資料寫入請求串流時可能會發生逾時。您可以使用 `UploadPartRequest` 設定明確逾時。

下列 C\$1 範例會使用低階分段上傳 API，將檔案上傳至 S3 儲存貯體。如需有關設定和執行程式碼範例的資訊，請參閱《[適用於 .NET 的 AWS SDK 開發人員指南》中的適用於 .NET 的 SDK 入門](https://docs.aws.amazon.com/sdk-for-net/latest/developer-guide/net-dg-setup.html)。 *AWS *

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

namespace Amazon.DocSamples.S3
{
    class UploadFileMPULowLevelAPITest
    {
        private const string bucketName = "*** provide bucket name ***";
        private const string keyName = "*** provide a name for the uploaded object ***";
        private const string filePath = "*** provide the full path name of the file to upload ***";
        // Specify your bucket region (an example region is shown).
        private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2;
        private static IAmazonS3 s3Client;

        public static void Main()
        {
            s3Client = new AmazonS3Client(bucketRegion);
            Console.WriteLine("Uploading an object");
            UploadObjectAsync().Wait(); 
        }

        private static async Task UploadObjectAsync()
        {
            // Create list to store upload part responses.
            List<UploadPartResponse> uploadResponses = new List<UploadPartResponse>();

            // Setup information required to initiate the multipart upload.
            InitiateMultipartUploadRequest initiateRequest = new InitiateMultipartUploadRequest
            {
                BucketName = bucketName,
                Key = keyName
            };

            // Initiate the upload.
            InitiateMultipartUploadResponse initResponse =
                await s3Client.InitiateMultipartUploadAsync(initiateRequest);

            // Upload parts.
            long contentLength = new FileInfo(filePath).Length;
            long partSize = 5 * (long)Math.Pow(2, 20); // 5 MB

            try
            {
                Console.WriteLine("Uploading parts");
        
                long filePosition = 0;
                for (int i = 1; filePosition < contentLength; i++)
                {
                    UploadPartRequest uploadRequest = new UploadPartRequest
                        {
                            BucketName = bucketName,
                            Key = keyName,
                            UploadId = initResponse.UploadId,
                            PartNumber = i,
                            PartSize = partSize,
                            FilePosition = filePosition,
                            FilePath = filePath
                        };

                    // Track upload progress.
                    uploadRequest.StreamTransferProgress +=
                        new EventHandler<StreamTransferProgressArgs>(UploadPartProgressEventCallback);

                    // Upload a part and add the response to our list.
                    uploadResponses.Add(await s3Client.UploadPartAsync(uploadRequest));

                    filePosition += partSize;
                }

                // Setup to complete the upload.
                CompleteMultipartUploadRequest completeRequest = new CompleteMultipartUploadRequest
                    {
                        BucketName = bucketName,
                        Key = keyName,
                        UploadId = initResponse.UploadId
                     };
                completeRequest.AddPartETags(uploadResponses);

                // Complete the upload.
                CompleteMultipartUploadResponse completeUploadResponse =
                    await s3Client.CompleteMultipartUploadAsync(completeRequest);
            }
            catch (Exception exception)
            {
                Console.WriteLine("An AmazonS3Exception was thrown: { 0}", exception.Message);

                // Abort the upload.
                AbortMultipartUploadRequest abortMPURequest = new AbortMultipartUploadRequest
                {
                    BucketName = bucketName,
                    Key = keyName,
                    UploadId = initResponse.UploadId
                };
               await s3Client.AbortMultipartUploadAsync(abortMPURequest);
            }
        }
        public static void UploadPartProgressEventCallback(object sender, StreamTransferProgressArgs e)
        {
            // Process event. 
            Console.WriteLine("{0}/{1}", e.TransferredBytes, e.TotalBytes);
        }
    }
}
```

------
#### [ PHP ]

本主題說明如何使用 第 3 版的低階`uploadPart`方法 適用於 PHP 的 AWS SDK ，以多個部分上傳檔案。如需適用於 Ruby 的 AWS SDK API 的詳細資訊，請前往[AWS 適用於 Ruby 的 SDK - 第 2 版](https://docs.aws.amazon.com/sdkforruby/api/index.html)。

下列 PHP 範例會使用低階 PHP API 分段上傳，將檔案上傳至 Amazon S3 儲存貯體。

```
 require 'vendor/autoload.php';

use Aws\S3\Exception\S3Exception;
use Aws\S3\S3Client;

$bucket = '*** Your Bucket Name ***';
$keyname = '*** Your Object Key ***';
$filename = '*** Path to and Name of the File to Upload ***';

$s3 = new S3Client([
    'version' => 'latest',
    'region'  => 'us-east-1'
]);

$result = $s3->createMultipartUpload([
    'Bucket'       => $bucket,
    'Key'          => $keyname,
    'StorageClass' => 'REDUCED_REDUNDANCY',
    'Metadata'     => [
        'param1' => 'value 1',
        'param2' => 'value 2',
        'param3' => 'value 3'
    ]
]);
$uploadId = $result['UploadId'];

// Upload the file in parts.
try {
    $file = fopen($filename, 'r');
    $partNumber = 1;
    while (!feof($file)) {
        $result = $s3->uploadPart([
            'Bucket'     => $bucket,
            'Key'        => $keyname,
            'UploadId'   => $uploadId,
            'PartNumber' => $partNumber,
            'Body'       => fread($file, 5 * 1024 * 1024),
        ]);
        $parts['Parts'][$partNumber] = [
            'PartNumber' => $partNumber,
            'ETag' => $result['ETag'],
        ];
        $partNumber++;

        echo "Uploading part $partNumber of $filename." . PHP_EOL;
    }
    fclose($file);
} catch (S3Exception $e) {
    $result = $s3->abortMultipartUpload([
        'Bucket'   => $bucket,
        'Key'      => $keyname,
        'UploadId' => $uploadId
    ]);

    echo "Upload of $filename failed." . PHP_EOL;
}

// Complete the multipart upload.
$result = $s3->completeMultipartUpload([
    'Bucket'   => $bucket,
    'Key'      => $keyname,
    'UploadId' => $uploadId,
    'MultipartUpload'    => $parts,
]);
$url = $result['Location'];

echo "Uploaded $filename to $url." . PHP_EOL;
```

------

## 使用 適用於 Ruby 的 AWS SDK
<a name="mpuoverview-ruby-sdk"></a>

第 3 適用於 Ruby 的 AWS SDK 版支援以兩種方式進行 Amazon S3 分段上傳。第一個選項是可以使用受管檔案上傳。如需詳細資訊，請參閱 *AWS 開發人員部落格*中的[將檔案上傳至 Amazon S3](https://aws.amazon.com/blogs/developer/uploading-files-to-amazon-s3/)。受管檔案上傳是上傳檔案至儲存貯體的推薦方式。他們具有以下優點：
+ 管理大於 15 MB 的物件之分段上傳。
+ 以二進位模式正確開啟檔案，避免編碼問題。
+ 使用多執行緒平行分段上傳大型物件。

或者，您可以直接使用以下分段上傳用戶端操作。
+ [create\$1multipart\$1upload](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Client.html#create_multipart_upload-instance_method) – 啟動分段上傳並傳回上傳 ID。
+ [upload\$1part](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Client.html#upload_part-instance_method) – 以分段上傳上傳片段。
+ [upload\$1part\$1copy](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Client.html#upload_part_copy-instance_method) – 複製現有物件資料作為資料來源，以上傳片段。
+ [complete\$1multipart\$1upload](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Client.html#complete_multipart_upload-instance_method) – 組合先前已上傳的片段，以完成分段上傳。
+ [abort\$1multipart\$1upload](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Client.html#abort_multipart_upload-instance_method) – 停止分段上傳。

# 使用高階 .NET TransferUtility 類別上傳目錄
<a name="HLuploadDirDotNet"></a>

您可以使用 `TransferUtility` 類別，上傳整個目錄。根據預設，API 只會上傳指定目錄之根目錄中的檔案。但您可以指定以遞迴方式，上傳所有子目錄中的檔案。

也可以根據一些篩選條件，指定篩選運算式，來選取指定目錄中的檔案。例如，若只要從目錄上傳 `PDF` 檔案，可以指定 `"*.pdf"` 篩選運算式。

從目錄上傳檔案時，無法指定結果物件的金鑰名稱。Amazon S3 使用原始檔案路徑，建構金鑰名稱。例如，假設您有一個目錄為 `c:\myfolder`，其結構如下：

**Example**  

```
1. C:\myfolder
2.       \a.txt
3.       \b.pdf
4.       \media\               
5.              An.mp3
```

當您上傳此目錄時，Amazon S3 會使用下列金鑰名稱：

**Example**  

```
1. a.txt
2. b.pdf
3. media/An.mp3
```

**Example**  
下列 C\$1 範例會將目錄上傳至 Amazon S3 儲存貯體。此顯示如何使用不同的 `TransferUtility.UploadDirectory` 多載上傳目錄。每個後續的呼叫都會上傳取代前一個上傳。如需有關設定和執行程式碼範例的資訊，請參閱《[適用於 .NET 的 AWS SDK 開發人員指南》中的適用於 .NET 的 SDK 入門](https://docs.aws.amazon.com/sdk-for-net/latest/developer-guide/net-dg-setup.html)。 *AWS *  

```
using Amazon;
using Amazon.S3;
using Amazon.S3.Transfer;
using System;
using System.IO;
using System.Threading.Tasks;

namespace Amazon.DocSamples.S3
{
    class UploadDirMPUHighLevelAPITest
    {
        private const string existingBucketName = "*** bucket name ***";
        private const string directoryPath = @"*** directory path ***";
        // The example uploads only .txt files.
        private const string wildCard = "*.txt";
        // Specify your bucket region (an example region is shown).
        private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2;
        private static IAmazonS3 s3Client;
        static void Main()
        {
            s3Client = new AmazonS3Client(bucketRegion);
            UploadDirAsync().Wait();
        }

        private static async Task UploadDirAsync()
        {
            try
            {
                var directoryTransferUtility =
                    new TransferUtility(s3Client);

                // 1. Upload a directory.
                await directoryTransferUtility.UploadDirectoryAsync(directoryPath,
                    existingBucketName);
                Console.WriteLine("Upload statement 1 completed");

                // 2. Upload only the .txt files from a directory 
                //    and search recursively. 
                await directoryTransferUtility.UploadDirectoryAsync(
                                               directoryPath,
                                               existingBucketName,
                                               wildCard,
                                               SearchOption.AllDirectories);
                Console.WriteLine("Upload statement 2 completed");

                // 3. The same as Step 2 and some optional configuration. 
                //    Search recursively for .txt files to upload.
                var request = new TransferUtilityUploadDirectoryRequest
                {
                    BucketName = existingBucketName,
                    Directory = directoryPath,
                    SearchOption = SearchOption.AllDirectories,
                    SearchPattern = wildCard
                };

                await directoryTransferUtility.UploadDirectoryAsync(request);
                Console.WriteLine("Upload statement 3 completed");
            }
            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);
            }
        }
    }
}
```

# 列出分段上傳
<a name="list-mpu"></a>

您可以使用 AWS CLI、REST API 或 AWS SDKs，在 Amazon S3 中擷取進行中分段上傳的清單。您可以使用分段上傳，以程式設計方式將單一物件上傳到 Amazon S3。分段上傳會一次移動一部分物件資料，將物件移至 Amazon S3。如需更多分段上傳的一般資訊，請參閱[在 Amazon S3 中使用分段上傳來上傳和複製物件](mpuoverview.md)。

如需搭配額外檢查總和使用分段上傳來上傳物件的端對端程序，請參閱[教學課程：透過分段上傳來上傳物件並驗證其資料完整性](tutorial-s3-mpu-additional-checksums.md)。

下一節說明如何使用 AWS Command Line Interface、Amazon S3 REST API 和 AWS SDKs 列出進行中的分段上傳。

## 使用 列出分段上傳 AWS CLI
<a name="list-mpu-cli"></a>

中的下列各節 AWS Command Line Interface 說明列出分段上傳的操作。
+ [list-parts](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/list-parts.html) – 列出特定分段上傳的已上傳部分。
+ [list-multipart-uploads](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-multipart-uploads.html) – 列表進行中的分段上傳。

# 使用 REST API 列出分段上傳
<a name="list-mpu-rest"></a>

《Amazon Simple Storage Service API 參考》**中的下列章節說明了列出分段上傳的 REST API：
+ [ListParts](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html) - 列出特定分段上傳的已上傳部分。
+ [ListMultipartUploads](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html) - 列出進行中的分段上傳。

## 使用 AWS SDK 列出分段上傳 （低階 API)
<a name="list-aws-sdk"></a>

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

若要使用適用於 Java 的 AWS SDK 列出儲存貯體上的所有進行中分段上傳，您可以使用低階 API 類別來：


**低階 API 分段上傳列出程序**  

|  |  | 
| --- |--- |
| 1 | 建立 `ListMultipartUploadsRequest` 類別的執行個體，並提供儲存貯體名稱。 | 
| 2 | 執行 S3Client `listMultipartUploads` 方法。此方法會傳回 `ListMultipartUploadsResponse` 類別的執行個體，提供您進行中分段上傳的相關資訊。 | 

如需如何使用適用於 Java 的 AWS SDK 列出分段上傳的範例，請參閱《*Amazon S3 API 參考*》中的[列出分段上傳](https://docs.aws.amazon.com/AmazonS3/latest/API/s3_example_s3_ListMultipartUploads_section.html)。

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

若要列出特定儲存貯體上所有進行中的分段上傳，請使用 適用於 .NET 的 SDK 低階分段上傳 API 的 `ListMultipartUploadsRequest` 類別。`AmazonS3Client.ListMultipartUploads` 方法會傳回 `ListMultipartUploadsResponse` 類別的執行個體，提供進行中分段上傳的相關資訊。

進行中的分段上傳是已使用起始分段上傳請求啟動，但尚未完成或停止的分段上傳。如需 Amazon S3 分段上傳的詳細資訊，請參閱 [在 Amazon S3 中使用分段上傳來上傳和複製物件](mpuoverview.md)。

下列 C\$1 範例示範如何使用 適用於 .NET 的 SDK 列出儲存貯體上所有進行中的分段上傳。如需有關設定和執行程式碼範例的資訊，請參閱《[適用於 .NET 的 AWS SDK 開發人員指南》中的適用於 .NET 的 SDK 入門](https://docs.aws.amazon.com/sdk-for-net/latest/developer-guide/net-dg-setup.html)。 *AWS *

```
ListMultipartUploadsRequest request = new ListMultipartUploadsRequest
{
	 BucketName = bucketName // Bucket receiving the uploads.
};

ListMultipartUploadsResponse response = await AmazonS3Client.ListMultipartUploadsAsync(request);
```

------
#### [ PHP ]

本主題說明如何使用 第 3 版的低階 API 類別 適用於 PHP 的 AWS SDK ，列出儲存貯體上所有進行中的分段上傳。如需適用於 Ruby 的 AWS SDK API 的詳細資訊，請前往[AWS 適用於 Ruby 的 SDK - 第 2 版](https://docs.aws.amazon.com/sdkforruby/api/index.html)。

下列 PHP 範例示範如何列出儲存貯體上所有進行中的分段上傳。

```
 require 'vendor/autoload.php';

use Aws\S3\S3Client;

$bucket = '*** Your Bucket Name ***';

$s3 = new S3Client([
    'version' => 'latest',
    'region'  => 'us-east-1'
]);

// Retrieve a list of the current multipart uploads.
$result = $s3->listMultipartUploads([
    'Bucket' => $bucket
]);

// Write the list of uploads to the page.
print_r($result->toArray());
```

------

# 使用 AWS SDKs 追蹤分段上傳
<a name="track-mpu"></a>

您可以使用接聽程式介面追蹤物件上傳至 Amazon S3 的進度。高階分段上傳 API 提供這類接聽程式介面，稱為 `ProgressListener`。進度事件定期發生，並會通知接聽程式已傳輸的位元組數。如需更多分段上傳的一般資訊，請參閱[在 Amazon S3 中使用分段上傳來上傳和複製物件](mpuoverview.md)。

如需搭配額外檢查總和使用分段上傳來上傳物件的端對端程序，請參閱[教學課程：透過分段上傳來上傳物件並驗證其資料完整性](tutorial-s3-mpu-additional-checksums.md)。

下一節說明如何使用 AWS SDKs 追蹤分段上傳。

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

**Example**  
下列 Java 程式碼會上傳檔案，並使用 `ExecutionInterceptor` 追蹤上傳進度。如需如何建立和測試工作範例的說明，請參閱《 適用於 Java 的 AWS SDK 2.x 開發人員指南》中的[入門](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html)。  

```
import java.nio.file.Paths;

import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.core.async.AsyncRequestBody;
import software.amazon.awssdk.core.interceptor.Context;
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;
import software.amazon.awssdk.services.s3.S3AsyncClient;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;

public class TrackMPUProgressUsingHighLevelAPI {

    static class ProgressListener implements ExecutionInterceptor {
        private long transferredBytes = 0;

        @Override
        public void beforeTransmission(Context.BeforeTransmission context, ExecutionAttributes executionAttributes) {
            if (context.httpRequest().firstMatchingHeader("Content-Length").isPresent()) {
                String contentLength = context.httpRequest().firstMatchingHeader("Content-Length").get();
                long partSize = Long.parseLong(contentLength);
                transferredBytes += partSize;
                System.out.println("Transferred bytes: " + transferredBytes);
            }
        }
    }

    public static void main(String[] args) throws Exception {
        String existingBucketName = "*** Provide bucket name ***";
        String keyName = "*** Provide object key ***";
        String filePath = "*** file to upload ***";

        S3AsyncClient s3Client = S3AsyncClient.builder()
                .credentialsProvider(ProfileCredentialsProvider.create())
                .overrideConfiguration(c -> c.addExecutionInterceptor(new ProgressListener()))
                .build();

        // For more advanced uploads, you can create a request object
        // and supply additional request parameters (ex: progress listeners,
        // canned ACLs, etc.)
        PutObjectRequest request = PutObjectRequest.builder()
                .bucket(existingBucketName)
                .key(keyName)
                .build();

        AsyncRequestBody requestBody = AsyncRequestBody.fromFile(Paths.get(filePath));

        // You can ask the upload for its progress, or you can
        // add a ProgressListener to your request to receive notifications
        // when bytes are transferred.
        // S3AsyncClient processes all transfers asynchronously,
        // so this call will return immediately.
        var upload = s3Client.putObject(request, requestBody);

        try {
            // You can block and wait for the upload to finish
            upload.join();
        } catch (Exception exception) {
            System.out.println("Unable to upload file, upload aborted.");
            exception.printStackTrace();
        } finally {
            s3Client.close();
        }
    }
}
```

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

下列 C\$1 範例會示範將檔案上傳至 S3 儲存貯體，透過使用 `TransferUtility` 類別，和追蹤上傳作業進度。如需有關設定和執行程式碼範例的資訊，請參閱《[適用於 .NET 的 AWS SDK 開發人員指南》中的適用於 .NET 的 SDK 入門](https://docs.aws.amazon.com/sdk-for-net/latest/developer-guide/net-dg-setup.html)。 *AWS *

```
using Amazon;
using Amazon.S3;
using Amazon.S3.Transfer;
using System;
using System.Threading.Tasks;

namespace Amazon.DocSamples.S3
{
    class TrackMPUUsingHighLevelAPITest
    {
        private const string bucketName = "*** provide the bucket name ***";
        private const string keyName = "*** provide the name for the uploaded object ***";
        private const string filePath = " *** provide the full path name of the file to upload **";
        // Specify your bucket region (an example region is shown).
        private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2;
        private static IAmazonS3 s3Client;


        public static void Main()
        {
            s3Client = new AmazonS3Client(bucketRegion);
            TrackMPUAsync().Wait();
        }

        private static async Task TrackMPUAsync()
        {
            try
            {
                var fileTransferUtility = new TransferUtility(s3Client);

                // Use TransferUtilityUploadRequest to configure options.
                // In this example we subscribe to an event.
                var uploadRequest =
                    new TransferUtilityUploadRequest
                    {
                        BucketName = bucketName,
                        FilePath = filePath,
                        Key = keyName
                    };

                uploadRequest.UploadProgressEvent +=
                    new EventHandler<UploadProgressArgs>
                        (uploadRequest_UploadPartProgressEvent);

                await fileTransferUtility.UploadAsync(uploadRequest);
                Console.WriteLine("Upload completed");
            }
            catch (AmazonS3Exception e)
            {
                Console.WriteLine("Error encountered on server. Message:'{0}' when writing an object", e.Message);
            }
            catch (Exception e)
            {
                Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message);
            }
        }

        static void uploadRequest_UploadPartProgressEvent(object sender, UploadProgressArgs e)
        {
            // Process event.
            Console.WriteLine("{0}/{1}", e.TransferredBytes, e.TotalBytes);
        }
    }
}
```

------

# 中止分段上傳
<a name="abort-mpu"></a>

啟動分段上傳之後，開始上傳組件。Amazon S3 會儲存這些組件，而且只有在您上傳所有組件並傳送完成分段上傳的請求之後，才會建立物件。收到完成分段上傳的要求時，Amazon S3 就會組合這些組件來建立物件。如果未能成功傳送完成分段上傳請求，S3 就不會組合這些組件，也不會建立任何物件。如果您在上傳組件之後不想完成分段上傳，您應該中止分段上傳。

系統會向您收取與已上傳部分相關的所有儲存空間費用。建議一律完成分段上傳或停止分段上傳，以移除任何上傳的組件。如需定價的詳細資訊，請參閱 [分段上傳與定價](mpuoverview.md#mpuploadpricing)。

您也可以使用儲存貯體生命週期組態停止未完成的分段上傳。如需詳細資訊，請參閱[設定儲存貯體生命週期組態，以刪除不完整的分段上傳](mpu-abort-incomplete-mpu-lifecycle-config.md)。

下一節說明如何使用 AWS Command Line Interface、REST API 或 AWS SDKs 在 Amazon S3 中停止進行中的分段上傳。

## 使用 AWS CLI
<a name="abort-mpu-cli"></a>

如需使用 AWS CLI 停止分段上傳的詳細資訊，請參閱《 *AWS CLI 命令參考*》中的 [abort-multipart-upload](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/abort-multipart-upload.html)。

## 使用 REST API
<a name="abort-mpu-rest"></a>

如需使用 REST API 停止分段上傳的詳細資訊，請參閱《Amazon Simple Storage Service API 參考》**中的 [AbortMultiPartupLoad](https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html)。

## 使用 AWS SDKs（高階 API)
<a name="abort-mpu-high-level"></a>

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

若要使用適用於 Java 的 AWS SDK 停止進行中的分段上傳，您可以中止在指定日期之前啟動且仍在進行中的上傳。啟動上傳後，在尚未完成或停止之前，均視為進行中。

若要停止分段上傳，您可以：


|  |  | 
| --- |--- |
| 1 | 建立 S3Client 執行個體。 | 
| 2 | 傳遞儲存貯體名稱和其他必要參數，藉此可使用用戶端的中止方法。 | 

**注意**  
您也可以停止特定的分段上傳。如需詳細資訊，請參閱[使用 AWS SDKs（低階 API)](#abort-mpu-low-level)。

如需如何使用適用於 Java 的 AWS SDK 中止分段上傳的範例，請參閱《*Amazon S3 API 參考*》中的[取消分段上傳](https://docs.aws.amazon.com/AmazonS3/latest/API/s3_example_s3_AbortMultipartUpload_section.html)。

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

下列 C\$1 範例會示範停止一週前，於指定儲存貯體上開始且正在進行中的所有分段上傳。如需有關設定和執行程式碼範例的資訊，請參閱《[適用於 .NET 的 AWS SDK 開發人員指南》中的適用於 .NET 的 SDK 入門](https://docs.aws.amazon.com/sdk-for-net/latest/developer-guide/net-dg-setup.html)。 *AWS *

```
using Amazon;
using Amazon.S3;
using Amazon.S3.Transfer;
using System;
using System.Threading.Tasks;

namespace Amazon.DocSamples.S3
{
    class AbortMPUUsingHighLevelAPITest
    {
        private const string bucketName = "*** provide bucket name ***";
        // Specify your bucket region (an example region is shown).
        private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2;
        private static IAmazonS3 s3Client;

        public static void Main()
        {
            s3Client = new AmazonS3Client(bucketRegion);
            AbortMPUAsync().Wait();
        }

        private static async Task AbortMPUAsync()
        {
            try
            {
                var transferUtility = new TransferUtility(s3Client);

                // Abort all in-progress uploads initiated before the specified date.
                await transferUtility.AbortMultipartUploadsAsync(
                    bucketName, DateTime.Now.AddDays(-7));
            }
            catch (AmazonS3Exception e)
            {
                Console.WriteLine("Error encountered on server. Message:'{0}' when writing an object", e.Message);
            }
            catch (Exception e)
            {
                Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message);
            }
        } 
    }
}
```

**注意**  
您也可以停止特定的分段上傳。如需詳細資訊，請參閱[使用 AWS SDKs（低階 API)](#abort-mpu-low-level)。

------

## 使用 AWS SDKs（低階 API)
<a name="abort-mpu-low-level"></a>

您可呼叫 `AmazonS3.abortMultipartUpload` 方法，停止進行中的分段上傳。此方法會刪除已上傳至 Amazon S3 的所有部分，並釋出資源。您必須提供上傳 ID、儲存貯體名稱與金鑰名稱。下列 Java 程式碼範例示範如何停止進行中的分段上傳。

若要停止分段上傳，您要提供用於上傳的上傳 ID、儲存貯體和金鑰名稱。在停止分段上傳之後，即無法使用該上傳 ID 上傳其他部分。如需 Amazon S3 分段上傳的詳細資訊，請參閱 [在 Amazon S3 中使用分段上傳來上傳和複製物件](mpuoverview.md)。

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

若要使用適用於 Java 的 AWS SDK 停止特定的進行中分段上傳，您可以使用低階 API，提供儲存貯體名稱、物件金鑰和上傳 ID 來中止上傳。

**注意**  
您可以停止在特定時間之前啟動，且仍在進行中的所有分段上傳，而不是中止特定的分段上傳。此清除操作有助於停止您已啟動但未完成或停止的舊分段上傳。如需詳細資訊，請參閱[使用 AWS SDKs（高階 API)](#abort-mpu-high-level)。

如需如何使用適用於 Java 的 AWS SDK 中止特定分段上傳的範例，請參閱《*Amazon S3 API 參考*》中的[取消分段上傳](https://docs.aws.amazon.com/AmazonS3/latest/API/s3_example_s3_AbortMultipartUpload_section.html)。

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

下列 C\$1 範例示範如何停止分段上傳。如需包含下列程式碼的完整 C\$1 範例，請參閱 [使用 AWS SDKs（低階 API)](mpu-upload-object.md#mpu-upload-low-level)。

```
AbortMultipartUploadRequest abortMPURequest = new AbortMultipartUploadRequest
{
    BucketName = existingBucketName,
    Key = keyName,
    UploadId = initResponse.UploadId
};
await AmazonS3Client.AbortMultipartUploadAsync(abortMPURequest);
```

您也可以中止在特定時間之前啟動的所有進行中分段上傳。此清除操作有助於中止未完成或已中止的分段上傳。如需詳細資訊，請參閱[使用 AWS SDKs（高階 API)](#abort-mpu-high-level)。

------
#### [ PHP ]

此範例示範如何使用 適用於 PHP 的 AWS SDK 第 3 版中的類別來中止進行中的分段上傳。如需適用於 Ruby 的 AWS SDK API 的詳細資訊，請前往[AWS 適用於 Ruby 的 SDK - 第 2 版](https://docs.aws.amazon.com/sdkforruby/api/index.html)。範例中使用 `abortMultipartUpload()` 方法。

如需適用於 Ruby 的 AWS SDK API 的詳細資訊，請前往[AWS 適用於 Ruby 的 SDK - 第 2 版](https://docs.aws.amazon.com/sdkforruby/api/index.html)。

```
 require 'vendor/autoload.php';

use Aws\S3\S3Client;

$bucket = '*** Your Bucket Name ***';
$keyname = '*** Your Object Key ***';
$uploadId = '*** Upload ID of upload to Abort ***';

$s3 = new S3Client([
    'version' => 'latest',
    'region'  => 'us-east-1'
]);

// Abort the multipart upload.
$s3->abortMultipartUpload([
    'Bucket'   => $bucket,
    'Key'      => $keyname,
    'UploadId' => $uploadId,
]);
```

------

# 使用分段上傳來複製物件
<a name="CopyingObjectsMPUapi"></a>

分段上傳可讓您將物件以一組組件進行複製。本節中的範例示範如何使用分段上傳 API 來複製大於 5 GB 的物件。如需分段上傳的資訊，請參閱[在 Amazon S3 中使用分段上傳來上傳和複製物件](mpuoverview.md)。

您可以透過單一操作來複製小於 5 GB 的物件，而無需使用分段上傳 API。您可以使用 AWS 管理主控台、 AWS CLI、REST API 或 AWS SDKs物件。如需詳細資訊，請參閱[複製、移動和重新命名物件](copy-object.md)。

如需搭配額外檢查總和使用分段上傳來上傳物件的端對端程序，請參閱[教學課程：透過分段上傳來上傳物件並驗證其資料完整性](tutorial-s3-mpu-additional-checksums.md)。

下一節說明如何使用 REST API 或 AWS SDKs物件。

## 使用 REST API
<a name="CopyingObjctsUsingRESTMPUapi"></a>

《Amazon Simple Storage Service API 參考》**中的下列章節說明了分段上傳的 REST API。若要複製現有的物件，請使用分段上傳 (複製) API，並在要求中新增 `x-amz-copy-source` 要求標頭以指定來源物件。
+ [啟動分段上傳](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadInitiate.html)
+ [上傳片段](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadUploadPart.html)
+ [分段上傳 (複製)](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadUploadPartCopy.html)
+ [完成分段上傳](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadComplete.html)
+ [中止分段上傳](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadAbort.html)
+ [列出組件](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadListParts.html)
+ [列出分段上傳](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadListMPUpload.html)

您可以使用這些 API 來提出自己的 REST 請求，也可以使用我們所提供的其中一個 SDK。如需搭配 使用分段上傳的詳細資訊 AWS CLI，請參閱 [使用 AWS CLI](mpu-upload-object.md#UsingCLImpUpload)。如需 SDK 的詳細資訊，請參閱「[AWS 支援分段上傳的 SDK](mpuoverview.md#sdksupportformpu)」。

## 使用 AWS SDKs
<a name="copy-object-mpu-sdks"></a>

若要使用低階 API 複製物件，請執行以下步驟：
+ 呼叫 `AmazonS3Client.initiateMultipartUpload()` 方法以啟動分段上傳。
+ 儲存 `AmazonS3Client.initiateMultipartUpload()` 方法傳回之回應物件中的上傳 ID。您所提供的上傳 ID，用於每項分段上傳操作。
+ 複製所有的部分。為了每一個您需要複製的部分，建立一個新的 `CopyPartRequest` 類別執行個體。提供部分資訊，包含來源和目的地儲存貯體名稱、來源和目標物件金鑰、上傳 ID、部分的第一和最後的位元組位置與部分編號。
+ 儲存 `AmazonS3Client.copyPart()` 方法呼叫的回應。每一個回應包含 `ETag` 數值與上傳部分的編號。您需要此資訊才成完成分段上傳。
+ 呼叫 `AmazonS3Client.completeMultipartUpload()` 方法完成複製操作。

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

如需如何使用適用於 Java 的 AWS SDK 進行分段上傳來複製物件的範例，請參閱《*Amazon S3 API 參考*》中的[從另一個物件複製物件的一部分](https://docs.aws.amazon.com/AmazonS3/latest/API/s3_example_s3_UploadPartCopy_section.html)。

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

下列 C\$1 範例示範如何使用 適用於 .NET 的 SDK ，將大於 5 GB 的 Amazon S3 物件從一個來源位置複製到另一個來源位置，例如從一個儲存貯體複製到另一個儲存貯體。若要複製小於 5 GB 的物件，請使用「[使用 AWS SDKs](copy-object.md#CopyingObjectsUsingSDKs)」中，所描述的單一操作複製程序。如需 Amazon S3 分段上傳的詳細資訊，請參閱 [在 Amazon S3 中使用分段上傳來上傳和複製物件](mpuoverview.md)。

此範例示範如何使用 適用於 .NET 的 SDK 分段上傳 API，將大於 5 GB 的 Amazon S3 物件從一個 S3 儲存貯體複製到另一個儲存貯體。

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

namespace Amazon.DocSamples.S3
{
    class CopyObjectUsingMPUapiTest
    {
        private const string sourceBucket = "*** provide the name of the bucket with source object ***";
        private const string targetBucket = "*** provide the name of the bucket to copy the object to ***";
        private const string sourceObjectKey = "*** provide the name of object to copy ***";
        private const string targetObjectKey = "*** provide the name of the object copy ***";
        // Specify your bucket region (an example region is shown).
        private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2; 
        private static IAmazonS3 s3Client;

        public static void Main()
        {
            s3Client = new AmazonS3Client(bucketRegion);
            Console.WriteLine("Copying an object");
            MPUCopyObjectAsync().Wait();
        }
        private static async Task MPUCopyObjectAsync()
        {
            // Create a list to store the upload part responses.
            List<UploadPartResponse> uploadResponses = new List<UploadPartResponse>();
            List<CopyPartResponse> copyResponses = new List<CopyPartResponse>();

            // Setup information required to initiate the multipart upload.
            InitiateMultipartUploadRequest initiateRequest =
                new InitiateMultipartUploadRequest
                {
                    BucketName = targetBucket,
                    Key = targetObjectKey
                };

            // Initiate the upload.
            InitiateMultipartUploadResponse initResponse =
                await s3Client.InitiateMultipartUploadAsync(initiateRequest);

            // Save the upload ID.
            String uploadId = initResponse.UploadId;

            try
            {
                // Get the size of the object.
                GetObjectMetadataRequest metadataRequest = new GetObjectMetadataRequest
                {
                    BucketName = sourceBucket,
                    Key = sourceObjectKey
                };

                GetObjectMetadataResponse metadataResponse =
                    await s3Client.GetObjectMetadataAsync(metadataRequest);
                long objectSize = metadataResponse.ContentLength; // Length in bytes.

                // Copy the parts.
                long partSize = 5 * (long)Math.Pow(2, 20); // Part size is 5 MB.

                long bytePosition = 0;
                for (int i = 1; bytePosition < objectSize; i++)
                {
                    CopyPartRequest copyRequest = new CopyPartRequest
                    {
                        DestinationBucket = targetBucket,
                        DestinationKey = targetObjectKey,
                        SourceBucket = sourceBucket,
                        SourceKey = sourceObjectKey,
                        UploadId = uploadId,
                        FirstByte = bytePosition,
                        LastByte = bytePosition + partSize - 1 >= objectSize ? objectSize - 1 : bytePosition + partSize - 1,
                        PartNumber = i
                    };

                    copyResponses.Add(await s3Client.CopyPartAsync(copyRequest));

                    bytePosition += partSize;
                }

                // Set up to complete the copy.
                CompleteMultipartUploadRequest completeRequest =
                new CompleteMultipartUploadRequest
                {
                    BucketName = targetBucket,
                    Key = targetObjectKey,
                    UploadId = initResponse.UploadId
                };
                completeRequest.AddPartETags(copyResponses);

                // Complete the copy.
                CompleteMultipartUploadResponse completeUploadResponse = 
                    await s3Client.CompleteMultipartUploadAsync(completeRequest);
            }
            catch (AmazonS3Exception e)
            {
                Console.WriteLine("Error encountered on server. Message:'{0}' when writing an object", e.Message);
            }
            catch (Exception e)
            {
                Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message);
            }
        }
    }
}
```

------

# 教學課程：透過分段上傳來上傳物件並驗證其資料完整性
<a name="tutorial-s3-mpu-additional-checksums"></a>

 您可利用分段上傳，將單一物件以一組組件進行上傳。每個組件都是物件資料的接續部分。您可依任何順序分別上傳這些物件組件。若任何組件的傳輸失敗，您可再次傳輸該組件，而不會影響其他組件。當物件的所有組件都全部上傳完後，Amazon S3 會將這些組件組合起來建立該物件。一般而言，當物件大小達到 100 MB 時，應考慮使用分段上傳，而不是以單次操作上傳物件。如需分段上傳的詳細資訊，請參閱「[在 Amazon S3 中使用分段上傳來上傳和複製物件](mpuoverview.md)」。如需分段上傳的相關限制，請參閱[Amazon S3 分段上傳限制](qfacts.md)。

 您可以使用檢查總和來驗證資產在複製之後保持不變。執行檢查總和涉及使用演算法來循序逐一查看檔案中的每個位元組。Amazon S3 提供多種檢查總和選項，用於檢查資料的完整性。建議您執行這些完整性檢查，以作為耐久性最佳實務，並確認每個位元組在未變更的情況下傳輸。Amazon S3 也支援下列演算法：SHA-1、SHA-256、CRC32 和 CRC32C。Amazon S3 使用上述一或多個演算法來計算額外檢查總和值，並將其儲存為物件中繼資料的一部分。如需總和檢查的詳細資訊，請參閱 [在 Amazon S3 中檢查物件完整性](checking-object-integrity.md)。

**目標**  
 在本教學課程中，您將了解如何使用分段上傳和透過 AWS 命令列界面 (AWS CLI) 的額外 SHA-256 檢查總和，將物件上傳至 Amazon S3。您也將了解如何透過計算上傳物件的 MD5 雜湊和 SHA-256 檢查總和，來檢查物件的資料完整性。

**Topics**
+ [先決條件](#mpu-prerequisites)
+ [步驟 1：建立大型檔案](#create-large-file-step1)
+ [步驟 2：將檔案分割成多個檔案](#split-large-file-step2)
+ [步驟 3：建立具有額外檢查總和的分段上傳](#create-multipart-upload-step3)
+ [步驟 4：上傳分段上傳的組件](#upload-parts-step4)
+ [步驟 5：列出分段上傳的所有組件](#list-parts-step5)
+ [步驟 6：完成分段上傳](#complete-multipart-upload-step6)
+ [步驟 7：確認物件已上傳至您的儲存貯體](#confirm-upload-step7)
+ [步驟 8：使用 MD5 檢查總和驗證物件完整性](#verify-object-integrity-step8)
+ [步驟 9：使用額外檢查總和驗證物件完整性](#verify-object-integrity-sha256-step9)
+ [步驟 10：清理您的資源](#clean-up-step10)

## 先決條件
<a name="mpu-prerequisites"></a>
+ 開始本教學課程之前，請確定您能夠存取 Amazon S3 儲存貯體，以便上傳至其中。如需詳細資訊，請參閱[建立一般用途儲存貯體](create-bucket-overview.md)。
+  您必須安裝並設定 AWS CLI。如果您未安裝 AWS CLI，請參閱《AWS Command Line Interface 使用者指南》**中的[安裝或更新至 AWS CLI的最新版本](https://docs.aws.amazon.com//cli/latest/userguide/getting-started-install.html)。
+ 或者，您也可以使用 ，從主控台執行 AWS CLI 命令 AWS CloudShell。 AWS CloudShell 是以瀏覽器為基礎的預先驗證 Shell，您可以直接從 啟動 AWS 管理主控台。如需詳細資訊，請參閱《AWS CloudShell 使用者指南》**中的[什麼是 CloudShell](https://docs.aws.amazon.com//cloudshell/latest/userguide/welcome.html) 和[開始使用 AWS CloudShell](https://docs.aws.amazon.com//cloudshell/latest/userguide/getting-started.html)。

## 步驟 1：建立大型檔案
<a name="create-large-file-step1"></a>

如果您已有可供上傳的檔案，則可以在本教學課程中使用該檔案。否則，請使用下列步驟建立 15 MB 的檔案。如需分段上傳的相關限制，請參閱[Amazon S3 分段上傳限制](qfacts.md)。

**建立大型檔案**

請根據您使用的作業系統，使用下列其中一個命令來建立檔案。

**Linux 或 macOS**  
若要建立 15 MB 的檔案，請開啟本機終端機並執行下列命令：

```
dd if=/dev/urandom of=census-data.bin bs=1M count=15
```

此命令會建立名為 `census-data.bin` 的檔案，並填入 15 MB 大小的隨機位元組。

**Windows**  
若要建立 15 MB 的檔案，請開啟本機終端機並執行下列命令：

```
fsutil file createnew census-data.bin 15728640
```

此命令會建立名為 `census-data.bin` 的檔案，其中包含 15 MB 大小的任意資料 (15728640 個位元組)。

## 步驟 2：將檔案分割成多個檔案
<a name="split-large-file-step2"></a>

若要執行分段上傳，您必須將大型檔案分割成較小的組件。然後，您可以使用分段上傳程序來上傳較小的組件。此步驟示範如何將[步驟 1](#create-large-file-step1) 中建立的大型檔案分割成較小的組件。下列範例使用名為 `census-data.bin` 的 15 MB 檔案。

**將大型檔案分割成組件**

**Linux 或 macOS**  
若要將大型檔案分割成 5 MB 的組件，請使用 `split` 命令。開啟您的終端機並執行下列命令：

```
split -b 5M -d census-data.bin census-part
```

此命令會將 `census-data.bin` 分割成名為 `census-part**` 的 5 MB 組件，其中 `**` 是從 `00` 開始的數字尾碼。

**Windows**  
若要分割大型檔案，請使用 PowerShell。開啟 [PowerShell](https://learn.microsoft.com/en-us/powershell/) 並執行下列指令碼：

```
$inputFile = "census-data.bin"
$outputFilePrefix = "census-part"
$chunkSize = 5MB

$fs = [System.IO.File]::OpenRead($inputFile)
$buffer = New-Object byte[] $chunkSize
$fileNumber = 0

while ($fs.Position -lt $fs.Length) {
$bytesRead = $fs.Read($buffer, 0, $chunkSize)
$outputFile = "{0}{1:D2}" -f $outputFilePrefix, $fileNumber
$fileStream = [System.IO.File]::Create($outputFile)
$fileStream.Write($buffer, 0, $bytesRead)
$fileStream.Close()
$fileNumber++
}

$fs.Close()
```

此 PowerShell 指令碼會將大型檔案分成 5 MB 區塊進行讀取，並將每個區塊寫入加上數字尾碼的新檔案。

執行適當的命令之後，您應該會在執行命令的目錄中看到這些組件。每個組件都有一個對應至其組件編號的尾碼，例如：

```
census-part00 census-part01 census-part02
```

## 步驟 3：建立具有額外檢查總和的分段上傳
<a name="create-multipart-upload-step3"></a>

若要開始分段上傳程序，您必須建立分段上傳請求。此步驟涉及啟動分段上傳，並為資料完整性指定額外檢查總和。下列範例使用 SHA-256 檢查總和。如果您想要提供任何中繼資料來描述正在上傳的物件，則必須在啟動分段上傳的請求中提供。

**注意**  
在此步驟和後續步驟中，本教學課程使用 SHA-256 的額外演算法。您可以選擇針對這些步驟使用另一個額外檢查總和，例如 CRC32、CRC32C 或 SHA-1。如果您使用不同的演算法，則必須在整個教學步驟中保持使用。

**開始分段上傳**

在您的終端機中，使用下列 `create-multipart-upload` 命令來開始為您的儲存貯體進行分段上傳。將 `amzn-s3-demo-bucket1` 取代為您實際的儲存貯體名稱。此外，將 `census_data_file` 取代為您選擇的檔案名稱。上傳完成時，此檔案名稱會成為物件金鑰。

```
aws s3api create-multipart-upload --bucket amzn-s3-demo-bucket1 --key 'census_data_file' --checksum-algorithm sha256
```

如果您的請求成功，您會看到如下所示的 JSON 輸出：

```
{
    "ServerSideEncryption": "AES256",
    "ChecksumAlgorithm": "SHA256",
    "Bucket": "amzn-s3-demo-bucket1",
    "Key": "census_data_file",
    "UploadId": "cNV6KCSNANFZapz1LUGPC5XwUVi1n6yUoIeSP138sNOKPeMhpKQRrbT9k0ePmgoOTCj9K83T4e2Gb5hQvNoNpCKqyb8m3.oyYgQNZD6FNJLBZluOIUyRE.qM5yhDTdhz"
}
```

**注意**  
當您傳送要求要啟動分段上傳時，Amazon S3 會傳回具有上傳 ID 的回應，其為分段上傳的唯一識別符。每次上傳分段各組件、列出各組件、完成上傳或停止上傳時，都必須納入此上傳 ID。您必須使用 `UploadId`、`Key` 和 `Bucket` 值進行後續步驟，因此請務必儲存這些值。  
此外，如果您搭配額外檢查總和使用分段上傳，則組件編號必須是連續的。如果您使用非連續的組件編號，`complete-multipart-upload` 請求可能會導致 HTTP `500 Internal Server Error`。

## 步驟 4：上傳分段上傳的組件
<a name="upload-parts-step4"></a>

在此步驟中，您會將分段上傳的組件上傳至 S3 儲存貯體。請使用 `upload-part` 命令來分別上傳每個組件。此程序需要指定上傳 ID、組件編號，以及每個組件要上傳的檔案。

**上傳組件**

1. 上傳組件時，除了上傳 ID 之外，還必須使用 `--part-number` 引數來指定組件編號。您可選擇 1 到 10,000 之間的任何組件編號。組件編號可找出獨特的某個組件，以及其在上傳中物件內的位置。您選擇的組件編號必須是連續的號碼 (例如，其可為 1、2 或 3)。若使用和前一個上傳組件相同的組件編號上傳新的組件，將會覆寫前一個已上傳的組件。

1. 使用 `upload-part` 命令上傳分段上傳的每個組件。`--upload-id` 與[步驟 3](#create-multipart-upload-step3) 中 `create-multipart-upload` 命令所建立輸出中的 ID 相同。若要上傳資料的第一個組件，請使用下列命令：

   ```
   aws s3api upload-part --bucket amzn-s3-demo-bucket1 --key 'census_data_file' --part-number 1 --body census-part00 --upload-id "cNV6KCSNANFZapz1LUGPC5XwUVi1n6yUoIeSP138sNOKPeMhpKQRrbT9k0ePmgoOTCj9K83T4e2Gb5hQvNoNpCKqyb8m3.oyYgQNZD6FNJLBZluOIUyRE.qM5yhDTdhz" --checksum-algorithm SHA256
   ```

   完成每個 `upload-part` 命令之後，您應該會看到如下列範例所示的輸出：

   ```
   {
       "ServerSideEncryption": "AES256",
       "ETag": "\"e611693805e812ef37f96c9937605e69\"",
       "ChecksumSHA256": "QLl8R4i4+SaJlrl8ZIcutc5TbZtwt2NwB8lTXkd3GH0="
   }
   ```

1. 對於後續組件，請相應地遞增組件編號：

   ```
   aws s3api upload-part --bucket amzn-s3-demo-bucket1 --key 'census_data_file' --part-number <part-number> --body <file-path> --upload-id "<your-upload-id>" --checksum-algorithm SHA256
   ```

   例如，使用下列命令來上傳第二個組件：

   ```
   aws s3api upload-part --bucket amzn-s3-demo-bucket1 --key 'census_data_file' --part-number 2 --body census-part01 --upload-id "cNV6KCSNANFZapz1LUGPC5XwUVi1n6yUoIeSP138sNOKPeMhpKQRrbT9k0ePmgoOTCj9K83T4e2Gb5hQvNoNpCKqyb8m3.oyYgQNZD6FNJLBZluOIUyRE.qM5yhDTdhz" --checksum-algorithm SHA256
   ```

   Amazon S3 會傳回每個上傳組件的實體標籤 (ETag) 和額外檢查總和作為回應中的標頭。

1. 繼續使用 `upload-part` 命令，直到您已上傳物件的所有組件為止。

## 步驟 5：列出分段上傳的所有組件
<a name="list-parts-step5"></a>

若要完成分段上傳，您需要該特定分段上傳已上傳的所有組件清單。`list-parts` 命令輸出提供儲存貯體名稱、金鑰、上傳 ID、組件編號、ETag、額外檢查總和等資訊。請將此輸出儲存在檔案中，以便您能夠在完成分段上傳程序時將其用於後續步驟。您可以使用下列方法建立名為 `parts.json`的 JSON 輸出檔案。

**建立列出所有組件的檔案**

1. 若要產生具有所有上傳組件詳細資訊的 JSON 檔案，請使用下列 `list-parts` 命令。將 ***amzn-s3-demo-bucket1*** 取代為您實際的儲存貯體名稱，並將 **<your-upload-id>** 取代為您在[步驟 3](#create-multipart-upload-step3) 中收到的上傳 ID。如需 `list-parts` 命令的詳細資訊，請參閱《AWS Command Line Interface 使用者指南》**中的[https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html)。

   ```
   aws s3api list-parts --bucket amzn-s3-demo-bucket1 --key 'census_data_file' --upload-id <your-upload-id> --query '{Parts: Parts[*].{PartNumber: PartNumber, ETag: ETag, ChecksumSHA256: ChecksumSHA256}}' --output json > parts.json
   ```

   這會產生名為 `parts.json` 的新檔案。該檔案包含所有上傳組件的 JSON 格式資訊。`parts.json` 檔案包含分段上傳之每個組件的基本資訊 (例如組件編號及其對應的 ETag 值)，完成分段上傳程序需要這些資訊。

1. 使用任何文字編輯器或透過終端機開啟 `parts.json`。以下是範例輸出：

   ```
   {
       "Parts": [
           {
               "PartNumber": 1,
               "ETag": "\"3c3097f89e2a2fece47ac54b243c9d97\"",
               "ChecksumSHA256": "fTPVHfyNHdv5VkR4S3EewdyioXECv7JBxN+d4FXYYTw="
           },
           {
               "PartNumber": 2,
               "ETag": "\"03c71cc160261b20ab74f6d2c476b450\"",
               "ChecksumSHA256": "VDWTa8enjOvULBAO3W2a6C+5/7ZnNjrnLApa1QVc3FE="
           },
           {
               "PartNumber": 3,
               "ETag": "\"81ae0937404429a97967dffa7eb4affb\"",
               "ChecksumSHA256": "cVVkXehUlzcwrBrXgPIM+EKQXPUvWist8mlUTCs4bg8="
           }
       ]
   }
   ```

## 步驟 6：完成分段上傳
<a name="complete-multipart-upload-step6"></a>

在分段上傳的所有組件都上傳並列出之後，最後一個步驟是完成分段上傳。此步驟會將所有上傳的組件合併為 S3 儲存貯體中的單一物件。

**注意**  
您可以在請求中加入 `--checksum-sha256` 來計算物件檢查總和，再呼叫 `complete-multipart-upload`。如果檢查總和不相符，Amazon S3 的請求會失敗。如需詳細資訊，請參閱《*AWS Command Line Interface 使用者指南》*中的 [https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html](https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html)。

**完成分段上傳**

若要完成分段上傳，請使用 `complete-multipart-upload` 命令。此命令需要[步驟 5](#list-parts-step5) 中建立的 `parts.json` 檔案、您的儲存貯體名稱和上傳 ID。將 **<*amzn-s3-demo-bucket1*>** 取代為您的儲存貯體名稱，並將 **<your-upload-id>** 取代為 `parts.json` 的上傳 ID。

```
aws s3api complete-multipart-upload --multipart-upload file://parts.json --bucket amzn-s3-demo-bucket1 --key 'census_data_file' --upload-id <your-upload-id>
```

以下是範例輸出：

```
{
    "ServerSideEncryption": "AES256",
    "Location": "https://amzn-s3-demo-bucket1.s3.us-east-2.amazonaws.com/census_data_file",
    "Bucket": "amzn-s3-demo-bucket1",
    "Key": "census_data_file",
    "ETag": "\"f453c6dccca969c457efdf9b1361e291-3\"",
    "ChecksumSHA256": "aI8EoktCdotjU8Bq46DrPCxQCGuGcPIhJ51noWs6hvk=-3"
}
```

**注意**  
先不要刪除個別組件檔案。您需要個別組件，才能對其執行檢查總和，以驗證合併在一起的物件完整性。

## 步驟 7：確認物件已上傳至您的儲存貯體
<a name="confirm-upload-step7"></a>

完成分段上傳之後，您可以確認物件是否已成功上傳至 S3 儲存貯體。若要列出您儲存貯體中的物件，並確認新上傳的檔案是否存在，請使用 `list-objects-v2` 命令 

**列出上傳的物件**

若要列出您儲存貯體中的物件，請使用 `list-objects-v2` 命令。將 ***amzn-s3-demo-bucket1*** 取代為您實際的儲存貯體名稱：

```
aws s3api list-objects-v2 --bucket amzn-s3-demo-bucket1
```

此命令會傳回您儲存貯體中的物件清單。在物件清單中尋找您上傳的檔案 (例如 `census_data_file`)。

如需詳細資訊，請參閱《AWS Command Line Interface 使用者指南》**中 `list-objects-v2` 命令的[範例](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-objects-v2.html)一節。

## 步驟 8：使用 MD5 檢查總和驗證物件完整性
<a name="verify-object-integrity-step8"></a>

當您上傳物件時，可指定 Amazon S3 要使用的檢查總和演算法。根據預設，Amazon S3 會將位元組的 MD5 摘要儲存為物件的 ETag。對於分段上傳，ETag 不是整個物件的檢查總和，而是每個組件的檢查總和複合。

**使用 MD5 檢查總和來驗證物件完整性**

1. 若要擷取上傳物件的 ETag，請執行 `head-object` 請求：

   ```
   aws s3api head-object --bucket amzn-s3-demo-bucket1 --key census_data_file
   ```

   以下是範例輸出：

   ```
   {
       "AcceptRanges": "bytes",
       "LastModified": "2024-07-26T19:04:13+00:00",
       "ContentLength": 16106127360,
       "ETag": "\"f453c6dccca969c457efdf9b1361e291-3\"",
       "ContentType": "binary/octet-stream",
       "ServerSideEncryption": "AES256",
       "Metadata": {}
   }
   ```

   此 ETag 已將 "-3" 附加至結尾。這表示使用分段上傳，將物件分三個組件上傳。

1. 接下來，使用 `md5sum` 命令計算每個組件的 MD5 檢查總和。請務必提供正確的組件檔案路徑：

   ```
   md5sum census-part*
   ```

   以下是範例輸出：

   ```
   e611693805e812ef37f96c9937605e69 census-part00
   63d2d5da159178785bfd6b6a5c635854 census-part01
   95b87c7db852451bb38b3b44a4e6d310 census-part02
   ```

1. 在此步驟中，手動將 MD5 雜湊合併為一個字串。然後，執行下列命令，將字串轉換為二進位，並計算二進位值的 MD5 檢查總和：

   ```
   echo "e611693805e812ef37f96c9937605e6963d2d5da159178785bfd6b6a5c63585495b87c7db852451bb38b3b44a4e6d310" | xxd -r -p | md5sum
   ```

   以下是範例輸出：

   ```
   f453c6dccca969c457efdf9b1361e291 -
   ```

   此雜湊值應符合[步驟 1](#create-large-file-step1) 中原始 ETag 值的雜湊值，才能驗證 `census_data_file` 物件的完整性。

當您指示 Amazon S3 使用額外的檢查總和時，Amazon S3 會計算每個部分的檢查總和值並儲存這些值。如果您想要在分段上傳仍在進行時，擷取個別組件的檢查總和值，則可以使用 `list-parts`。

如需如何搭配分段上傳物件使用檢查總和的詳細資訊，請參閱[在 Amazon S3 中檢查物件完整性](checking-object-integrity.md)。

## 步驟 9：使用額外檢查總和驗證物件完整性
<a name="verify-object-integrity-sha256-step9"></a>

在此步驟中，本教學課程使用 SHA-256 作為額外檢查總和，以驗證物件完整性。如果您使用了不同的額外檢查總和，請改用該檢查總和值。

**使用 SHA256 驗證物件完整性**

1. 在您的終端機中執行下列命令 (包括 `--checksum-mode enabled` 引數)，以顯示您物件的 `ChecksumSHA256` 值：

   ```
   aws s3api head-object --bucket amzn-s3-demo-bucket1 --key census_data_file --checksum-mode enabled
   ```

   以下是範例輸出：

   ```
   {
       "AcceptRanges": "bytes",
       "LastModified": "2024-07-26T19:04:13+00:00",
       "ContentLength": 16106127360,
       "ChecksumSHA256": "aI8EoktCdotjU8Bq46DrPCxQCGuGcPIhJ51noWs6hvk=-3",
       "ETag": "\"f453c6dccca969c457efdf9b1361e291-3\"",
       "ContentType": "binary/octet-stream",
       "ServerSideEncryption": "AES256",
       "Metadata": {}
   }
   ```

1. 使用下列命令，將個別組件的 `ChecksumSHA256` 值解碼為 base64，並將其儲存在名為 `outfile` 的二進位檔案中。您可以在 `parts.json` 檔案中找到這些值。將範例 base64 字串取代為您實際的 `ChecksumSHA256` 值。

   ```
   echo "QLl8R4i4+SaJlrl8ZIcutc5TbZtwt2NwB8lTXkd3GH0=" | base64 --decode >> outfile
   echo "xCdgs1K5Bm4jWETYw/CmGYr+m6O2DcGfpckx5NVokvE=" | base64 --decode >> outfile
   echo "f5wsfsa5bB+yXuwzqG1Bst91uYneqGD3CCidpb54mAo=" | base64 --decode >> outfile
   ```

1. 執行下列命令來計算 `outfile` 的 SHA256 檢查總和：

   ```
   sha256sum outfile
   ```

   以下是範例輸出：

   ```
   688f04a24b42768b6353c06ae3a0eb3c2c50086b8670f221279d67a16b3a86f9 outfile
   ```

   在下一個步驟中，取得雜湊值並將其轉換為二進位值。此二進位值應符合[步驟 1](#create-large-file-step1) 中的 `ChecksumSHA256` 值。

1. 將[步驟 3](#create-multipart-upload-step3) 中的 SHA256 檢查總和轉換為二進位，然後將其編碼為 base64，以確認其是否符合[步驟 1](#create-large-file-step1) 中的 `ChecksumSHA256` 值：

   ```
   echo "688f04a24b42768b6353c06ae3a0eb3c2c50086b8670f221279d67a16b3a86f9" | xxd -r -p | base64
   ```

   以下是範例輸出：

   ```
   aI8EoktCdotjU8Bq46DrPCxQCGuGcPIhJ51noWs6hvk=
   ```

   此輸出應確認 base64 輸出符合 `head-object` 命令輸出中的 `ChecksumSHA256` 值。如果輸出符合檢查總和值，則物件有效。

**重要**  
當您指示 Amazon S3 使用額外檢查總和時，Amazon S3 會計算每個組件的檢查總和值並儲存這些值。
如果您想要在分段上傳仍在進行時，擷取個別組件的檢查總和值，則可以使用 `list-parts` 命令。

## 步驟 10：清理您的資源
<a name="clean-up-step10"></a>

如果您想要清除在本教學課程中建立的檔案，請使用下列方法。如需刪除上傳至您 S3 儲存貯體之檔案的說明，請參閱[刪除 Amazon S3 物件](DeletingObjects.md)。

**刪除在[步驟 1](#create-large-file-step1) 中建立的本機檔案：**

若要移除您為分段上傳建立的檔案，請從您的工作目錄執行下列命令：

```
rm census-data.bin census-part* outfile parts.json
```

# Amazon S3 分段上傳限制
<a name="qfacts"></a>

您可利用分段上傳，將單一物件以一組組件進行上傳。每個組件都是物件資料的接續部分。當物件的所有組件都全部上傳完後，Amazon S3 會將這些組件組合起來建立該物件。一般而言，當物件大小達到 100 MB 時，應考慮使用分段上傳，而不是以單次操作上傳物件。如需分段上傳的詳細資訊，請參閱「[在 Amazon S3 中使用分段上傳來上傳和複製物件](mpuoverview.md)」。

下表提供分段上傳核心規格。這包括物件大小上限、組件數目上限、組件大小上限等。您的分段上傳的最後一部分沒有大小下限。


| 項目 | 規格 | 
| --- | --- | 
| 物件大小上限 | 48.8 TiB  | 
| 每次上傳的組件數目上限 | 10,000 | 
| 組件編號 | 1 到 10,000 (含) | 
| 組件大小 | 5 MiB 至 5 GiB。您的分段上傳的最後一部分沒有大小下限。 | 
| 列出組件要求的傳回組件數上限 | 1000  | 
| 列出分段上傳要求所傳回的分段上傳數目上限 | 1000  | 