

 **此页面仅适用于使用文件库和 2012 年原始 REST API 的 Amazon Glacier 服务的现有客户。**

如果您正在寻找归档存储解决方案，建议使用 Amazon S3 中的 Amazon Glacier 存储类别 S3 Glacier Instant Retrieval、S3 Glacier Flexible Retrieval 和 S3 Glacier Deep Archive。要了解有关这些存储选项的更多信息，请参阅 [Amazon Glacier 存储类别](https://aws.amazon.com/s3/storage-classes/glacier/)。

Amazon Glacier（最初基于保管库的独立服务）不再接受新客户。Amazon Glacier 是一项独立的服务 APIs ，拥有自己的服务，可将数据存储在文件库中，不同于亚马逊 S3 和 Amazon S3 Glacier 存储类别。在 Amazon Glacier 中，您现有的数据将确保安全，并且可以无限期地访问。无需进行迁移。对于低成本、长期的存档存储， AWS 建议[使用 Amazon S3 Glacier 存储类别，这些存储类别](https://aws.amazon.com/s3/storage-classes/glacier/)基于S3存储桶 APIs、完全 AWS 区域 可用性、更低的成本和 AWS 服务集成，可提供卓越的客户体验。如果您希望加强功能，可以考虑使用我们的 [AWS 将数据从 Amazon Glacier 文件库传输到 Amazon S3 Glacier 存储类别的解决方案指南](https://aws.amazon.com/solutions/guidance/data-transfer-from-amazon-s3-glacier-vaults-to-amazon-s3/)，迁移到 Amazon S3 Glacier 存储类别。

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 分段上传大型档案（分段上传）
<a name="uploading-archive-mpu"></a>

**Topics**
+ [分段上传流程](#MPUprocess)
+ [快讯](#qfacts)
+ [使用上传大型档案 AWS CLI](uploading-an-archive-mpu-using-cli.md)
+ [使用适用于 Java 的 Amazon SDK 分段上传大型档案](uploading-an-archive-mpu-using-java.md)
+ [使用上传大型档案 适用于 .NET 的 AWS SDK](uploading-an-archive-mpu-using-dotnet.md)
+ [使用 REST API 分段上传大型档案](uploading-an-archive-mpu-using-rest.md)

## 分段上传流程
<a name="MPUprocess"></a>

如[在 Amazon Glacier 中上传档案](uploading-an-archive.md)中所述，我们鼓励 Amazon Glacier（Amazon Glacier）客户使用分段上传来上传大于 100 兆字节（MiB）的档案。

1. **开始分段上传** 

   当您发送请求以启动分段上传时，Amazon Glacier 返回分段上传 ID，它是您分段上传的唯一标识符。后续的任何分段上传操作均需要此 ID。Amazon Glacier 完成任务后，此 ID 至少在 24 小时内都不会过期。

   在您启动分段上传的请求中，请指定段大小（以字节数为单位）。除了最后一段以外，您上传的每一段都必须为此大小。
**注意**  
使用分段上传时，您不需要知道整个档案大小。这意味着，在开始上传档案时，您可以在不知道档案大小的情况下使用分段上传。您只需在启动分段上传时决定段大小即可。

   此外，在启动分段上传请求中，您还可以提供可选的档案描述。

1. **上传段**

   对于每个段上传请求，您必须包括您在步骤 1 中获取的分段上传 ID。此外，在请求中，您还必须指定标识段在最终档案中的位置的内容范围（以字节为单位）。Amazon Glacier 稍后会使用内容范围信息来以适当顺序组装档案。由于您提供了上传的每一段的内容范围，因此，它会确定段在最终档案汇编中的位置，进而，您可以任何顺序上传段。此外，您还可以并行上传段。如果您使用与之前上传的段相同的内容范围上传新段，则之前上传的段会被覆盖。

1. **完成（或停止）分段上传**

   上传所有档案段后，您可以使用完成操作。此外，您还必须在请求中指定上传 ID。Amazon Glacier 将按您提供的内容范围以升序顺序组装各个分段，从而创建档案。Amazon Glacier 对“完成分段上传”请求的响应包括新创建的档案的档案 ID。如果您在“启动分段上传”请求中提供了可选的档案描述，则 Amazon Glacier 会将它与组装的档案相关联。成功完成分段上传后，您无法引用该分段上传 ID。这意味着，您无法访问与该分段上传 ID 相关联的段。

   如果停止分段上传，则您无法使用该分段上传 ID 上传其他任何段。与停止的分段上传相关联的任何段所占用的所有存储都会被释放。如果有任何分段上传正在进行，则即使在您停止后，它们仍然可能会成功或失败。

### 额外的分段上传操作
<a name="additional-mpu-operations"></a>

Amazon Glacier（Amazon Glacier）提供了以下额外的分段上传 API 调用。

 
+ **列出段** – 利用此操作，您可以列出特定分段上传的段。它会返回有关您为分段上传上传的段的信息。对于每个“列出段”请求，Amazon Glacier 最多返回 1000 段的信息。如果有更多段要为分段上传列出，则结果会分页，并且响应中会返回一个指示要从其所在位置继续列表的标记。您需要发送附加请求来检索后续的段。请注意，返回的段列表不包括未完成上传的段。
+ **列出分段上传** – 利用此操作，您可以获取正在进行的分段上传的列表。正在进行的分段上传是已开始但还未完成或停止的上传。对于每个列出分段上传请求，Amazon Glacier 最多会返回 1000 个分段上传。如果有更多分段上传要列出，则结果会分页，并且响应中会返回一个指示要从其所在位置继续列表的标记。您需要发送附加请求来检索剩余的分段上传。

## 快讯
<a name="qfacts"></a>

下表提供了分段上传的核心规范。


| Item | 规格 | 
| --- | --- | 
| 最大档案大小 | 10000 x 4 吉字节（GiB）  | 
| 每次上传的分段的最大数量 | 10000 | 
| 分段大小 | 1 MiB 到 4 GiB，最后一个分段可以小于 1 MiB。您可以指定大小值（以字节为单位）。 分段大小必须为兆字节（1024 KiB）乘以 2 的幂，例如，`1048576`（1 MiB）、`2097152`（2 MiB）、`4194304`（4 MiB）、`8388608`（8 MiB）。  | 
| 列出分段请求返回的分段的最大数量 | 1000  | 
| 在列出分段上传请求中返回的分段的最大数量 | 1000  | 

# 使用上传大型档案 AWS CLI
<a name="uploading-an-archive-mpu-using-cli"></a>

您可以使用 () 在 Amazon Glacier（Amazon Glacier AWS CLI）中 AWS Command Line Interface 上传档案。为了改善大型档案的上传体验，Amazon Glacier 提供了多个 API 操作来支持分段上传。通过这些 API 操作，您可以分段上传档案。您可以独立地、以任何顺序以及并行地上传这些段。如果某个分段上传失败，则您只需重新上传该分段，而无需重新上传整个档案。您可以对大小从 1 字节到大约 40000 GiB 的档案使用分段上传。

有关 Amazon Glacier 分段上传的更多信息，请参阅[分段上传大型档案（分段上传）](uploading-archive-mpu.md)。

**Topics**
+ [（先决条件）设置 AWS CLI](#Creating-Vaults-CLI-Setup)
+ [（先决条件）安装 Python](#Uploading-Archives-mpu-CLI-Install-Python)
+ [（先决条件）创建 Amazon Glacier 文件库](#Uploading-Archives-mpu-CLI-Create-Vault)
+ [示例：使用分段上传大型档案 AWS CLI](#Uploading-Archives-mpu-CLI-Implementation)

## （先决条件）设置 AWS CLI
<a name="Creating-Vaults-CLI-Setup"></a>

1. 下载并配置 AWS CLI。有关说明，请参阅《AWS Command Line Interface 用户指南》**中的以下主题：

    [正在安装 AWS Command Line Interface](https://docs.aws.amazon.com/cli/latest/userguide/installing.html) 

   [正在配置 AWS Command Line Interface](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html)

1. 在命令提示符下输入以下命令来验证您的 AWS CLI 设置。这些命令没有显式提供凭证，因此将使用默认配置文件的凭证。
   + 尝试使用 help 命令。

     ```
     aws help
     ```
   + 要获取已配置账户上 Amazon Glacier 文件库的列表，请使用 `list-vaults` 命令。*123456789012*用您的 AWS 账户 身份证替换。

     ```
     aws glacier list-vaults --account-id 123456789012
     ```
   + 要查看的当前配置数据 AWS CLI，请使用`aws configure list`命令。

     ```
     aws configure list
     ```

## （先决条件）安装 Python
<a name="Uploading-Archives-mpu-CLI-Install-Python"></a>

要完成分段上传，您必须计算所上传档案的 SHA256 树形哈希。这样做与计算要上传的文件的 SHA256 树形哈希值不同。要计算您正在上传的档案的 SHA256 树形哈希，可以使用 Java C\$1（使用.NET）或Python。在此示例中，您将使用 Python。有关使用 Java 或 C\$1 的说明，请参阅[计算校验和](checksum-calculations.md)。

有关安装 Python 的更多信息，请参阅《Boto3 开发人员指南》**中的[安装或更新 Python](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/quickstart.html#installation)。

## （先决条件）创建 Amazon Glacier 文件库
<a name="Uploading-Archives-mpu-CLI-Create-Vault"></a>

要使用下面的示例，必须至少创建一个 Amazon Glacier 文件库。有关如何创建文件库的更多信息，请参阅[在 Amazon Glacier 中创建文件库](creating-vaults.md)。

## 示例：使用分段上传大型档案 AWS CLI
<a name="Uploading-Archives-mpu-CLI-Implementation"></a>

在此示例中，您将创建一个文件并使用分段上传 API 操作将此文件分段上传到 Amazon Glacier。
**重要**  
在开始此过程之前，请确保您已执行所有先决条件的步骤。要上传档案，您必须创建并 AWS CLI 配置文件库，并准备好使用 Java C\$1 或Python计算 SHA256 树形哈希。

以下过程使用`initiate-multipart-upload``upload-multipart-part`、和`complete-multipart-upload` AWS CLI 命令。

有关所有这些命令的更多详细信息，请参阅《AWS CLI 命令参考》**中的 [https://docs.aws.amazon.com/cli/latest/reference/glacier/initiate-multipart-upload.html](https://docs.aws.amazon.com/cli/latest/reference/glacier/initiate-multipart-upload.html)、[https://docs.aws.amazon.com/cli/latest/reference/glacier/upload-multipart-part.html](https://docs.aws.amazon.com/cli/latest/reference/glacier/upload-multipart-part.html) 和 [https://docs.aws.amazon.com/cli/latest/reference/glacier/complete-multipart-upload.html](https://docs.aws.amazon.com/cli/latest/reference/glacier/complete-multipart-upload.html)。

1. 使用 [https://docs.aws.amazon.com/cli/latest/reference/glacier/initiate-multipart-upload.html](https://docs.aws.amazon.com/cli/latest/reference/glacier/initiate-multipart-upload.html) 命令创建分段上传资源。在您的请求中，请指定分段大小（以字节数为单位）。除了最后一个分段以外，您上传的每个分段都必须为此大小。启动上传任务时，您不需要知道整个档案的大小。但是，在最后一步完成上传时，您将需要知道每个分段的总大小（以字节为单位）。

   在下面的命令中，将 `--vault-name` 和 `--account-ID` 参数的值替换为您自己的信息。此命令指定每个文件将上传分段大小为 1 兆字节（MiB）（1024 x 1024 字节）的档案。如果需要，请替换此 `--part-size` 参数值。

   ```
   aws glacier initiate-multipart-upload --vault-name awsexamplevault --part-size 1048576 --account-id 123456789012
   ```

   预期输出：

   ```
   {
   "location": "/123456789012/vaults/awsexamplevault/multipart-uploads/uploadId",
   "uploadId": "uploadId"
   }
   ```

   完成后，该命令将输出分段上传资源的上传 ID 和在 Amazon Glacier 中的位置。在后续步骤中，您将使用此上传 ID。

1. 在本示例中，您可以使用以下命令创建一个 4.4 MiB 的文件，将其拆分为 1 MiB 的块，然后上传每个块。要上传自己的文件，您可以按照类似的步骤将数据拆分为多个块并上传每个分段。

   

**Linux 或 macOS**  
以下命令将在 Linux 或 macOS 上创建一个名为 `file_to_upload` 的 4.4 MiB 的文件。

   ```
   mkfile -n 9000b file_to_upload
   ```

**Windows**  
以下命令将在 Windows 上创建一个名为 `file_to_upload` 的 4.4 MiB 的文件。

   ```
   fsutil file createnew file_to_upload 4608000
   ```

1. 接下来，您将把此文件拆分为 1 MiB 的块。

   ```
   split -b 1048576 file_to_upload chunk
   ```

   您现在有以下五个块。前四个大小为 1 MiB，最后一个是 400 千字节（KiB）。

   ```
   chunkaa
   chunkab
   chunkac
   chunkad
   chunkae
   ```

1. 使用 [https://docs.aws.amazon.com/cli/latest/reference/glacier/upload-multipart-part.html](https://docs.aws.amazon.com/cli/latest/reference/glacier/upload-multipart-part.html) 命令以上传档案的一个分段。您可以按任何顺序上传档案分段。此外，您还可以并行上传分段。您最多可以为一个分段上传上传 10000 段。

   在下面的命令中，将替换 `--vault-name`、`--account-ID` 和 `--upload-id` 参数的值。上传 ID 必须与 `initiate-multipart-upload` 命令输出中提供的 ID 相匹配。`--range` 参数指定您将上传大小为 1 MiB（1024 x 1024 字节）的分段。此大小必须与您在 `initiate-multipart-upload` 命令中指定的大小一致。如有必要，请调整此大小值。`--body` 参数指定您要上传的分段的名称。

   ```
   aws glacier upload-multipart-part --body chunkaa --range='bytes 0-1048575/*' --vault-name awsexamplevault --account-id 123456789012 --upload-id upload_ID
   ```

   如果成功，该命令将生成包含已上传分段校验和的输出。

1. 再次运行 `upload-multipart-part` 命令以上传分段上传的其余部分。更新每个命令的 `--range` 和 `–-body` 参数值，使其与您要上传的分段相匹配。

   ```
   aws glacier upload-multipart-part --body chunkab --range='bytes 1048576-2097151/*' --vault-name awsexamplevault --account-id 123456789012 --upload-id upload_ID
   ```

   ```
   aws glacier upload-multipart-part --body chunkac --range='bytes 2097152-3145727/*' --vault-name awsexamplevault --account-id 123456789012 --upload-id upload_ID
   ```

   ```
   aws glacier upload-multipart-part --body chunkad --range='bytes 3145728-4194303/*' --vault-name awsexamplevault --account-id 123456789012 --upload-id upload_ID
   ```

   ```
   aws glacier upload-multipart-part --body chunkae --range='bytes 4194304-4607999/*' --vault-name awsexamplevault --account-id 123456789012 --upload-id upload_ID
   ```
**注意**  
最终命令的 `--range` 参数值较小，因为上传的最后一个分段小于 1 MiB。如果成功，每个命令都将生成包含每个已上传分段校验和的输出。

1. 接下来，您将接组档案并完成上传。您必须包括档案的总大小和 SHA256 树形哈希。

   要计算存档的 SHA256 树形哈希，可以使用 Java C\$1 或Python。在此示例中，您将使用 Python。有关使用 Java 或 C\$1 的说明，请参阅[计算校验和](checksum-calculations.md)。

   创建 Python 文件 `checksum.py` 并插入以下代码。如果需要，请替换原始文件的名称。

   ```
   from botocore.utils import calculate_tree_hash
   					
   checksum = calculate_tree_hash(open('file_to_upload', 'rb'))
   print(checksum)
   ```

1. 运行`checksum.py`计算 SHA256 树形哈希。以下哈希值可能与您的输出不匹配。

   ```
   $ python3 checksum.py
   $ 3d760edb291bfc9d90d35809243de092aea4c47b308290ad12d084f69988ae0c
   ```

1. 使用 [https://docs.aws.amazon.com/cli/latest/reference/glacier/complete-multipart-upload.html](https://docs.aws.amazon.com/cli/latest/reference/glacier/complete-multipart-upload.html) 命令完成档案上传。替换 `--vault-name`、`--account-ID`、`--upload-ID` 和 `--checksum` 参数的值。`--archive` 参数值以字节为单位指定档案的总大小。此值必须是为您上传的各段的所有大小之和。如果需要，请替换此值。

   ```
   aws glacier complete-multipart-upload --archive-size 4608000 --vault-name awsexamplevault --account-id 123456789012 --upload-id upload_ID --checksum checksum
   ```

   完成后，该命令将输出档案的 ID、校验和以及在 Amazon Glacier 中的位置。

# 使用适用于 Java 的 Amazon SDK 分段上传大型档案
<a name="uploading-an-archive-mpu-using-java"></a>

适用于 Java 的 Amazon SDK APIs 提供的[高级和低级](using-aws-sdk.md)都提供了一种上传大型档案的方法（参见[在 Amazon Glacier 中上传档案](uploading-an-archive.md)）。

 
+ 该高级 API 提供了您可以用来上传任何大小的档案的方法。根据您要上传的文件，该方法会在单个操作中上传档案或者使用 Amazon Glacier（Amazon Glacier）中的分段上传支持来分段上传档案。
+ 该低级 API 紧密映射到底层 REST 实施。因此，它提供了一个在单个操作中上传较小档案的方法，以及一组支持较大档案的分段上传的方法。此部分说明了使用低级 API 分段上传大型档案的操作。

有关高级和低级别的更多信息 APIs，请参阅[适用于 Java 的 AWS SDK 与 Amazon Glacier 搭配使用](using-aws-sdk-for-java.md)。

**Topics**
+ [使用的高级别 API 分段上传大型档案 适用于 Java 的 AWS SDK](#uploading-an-archive-in-parts-highlevel-using-java)
+ [使用的低级 API 分段上传大型档案 适用于 Java 的 AWS SDK](#uploading-an-archive-mpu-using-java-lowlevel)

## 使用的高级别 API 分段上传大型档案 适用于 Java 的 AWS SDK
<a name="uploading-an-archive-in-parts-highlevel-using-java"></a>

您可以使用高级 API 的相同方法上传小型或大型档案。根据档案大小，高级 API 方法会决定是在单个操作中上传档案，还是使用 Amazon Glacier 提供的分段上传 API 上传档案。有关更多信息，请参阅 [使用的高级别 API 上传档案 适用于 Java 的 AWS SDK](uploading-an-archive-single-op-using-java.md#uploading-an-archive-single-op-high-level-using-java)。

## 使用的低级 API 分段上传大型档案 适用于 Java 的 AWS SDK
<a name="uploading-an-archive-mpu-using-java-lowlevel"></a>

对于上传的粒度控制，您可以使用低级 API（您可以在其中配置请求以及处理响应）。以下是使用 适用于 Java 的 AWS SDK分段上传大型档案的步骤。

 

1. 创建 `AmazonGlacierClient` 类（客户端）的实例。

   您需要指定要保存档案的 AWS 区域。您使用此客户端执行的所有操作都适用于该 AWS 区域。

1. 通过调用 `initiateMultipartUpload` 方法启动分段上传。

   您需要提供要上传档案的文件库名称、要上传的档案段的大小，也可选择提供相关描述。您可以通过创建 `InitiateMultipartUploadRequest` 类的实例提供此信息。作为响应，Amazon Glacier 会返回上传 ID。

1. 通过调用 `uploadMultipartPart` 方法上传段。

   对于要上传的每一段，您需要提供文件库名称、将在此段中上传的最终组合档案的字节范围、段数据的校验和，以及上传 ID。

1. 通过调用 `completeMultipartUpload` 方法完成分段上传。

   您需要提供上传 ID、整个档案的校验和、档案大小（您上传的所有段的组合大小）和文件库名称。Amazon Glacier 从上传的分段构造档案并返回档案 ID。

### 示例：使用分段上传大型档案 适用于 Java 的 AWS SDK
<a name="upload-archive-mpu-java-example"></a>

以下 Java 代码示例使用将档案上传 适用于 Java 的 AWS SDK 到文件库 (`examplevault`)。有关如何运行此示例的 step-by-step说明，请参阅[使用 Eclipse 运行 Amazon Glacier 的 Java 示例](using-aws-sdk-for-java.md#setting-up-and-testing-sdk-java)。您需要更新待上传文件名称旁所显示的代码。

 

**注意**  
此示例对 1 MB 到 1 GB 的段大小有效。但是，Amazon Glacier 最大支持 4 GB 的段大小。

**Example**  

```
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.services.glacier.AmazonGlacierClient;
import com.amazonaws.services.glacier.TreeHashGenerator;
import com.amazonaws.services.glacier.model.CompleteMultipartUploadRequest;
import com.amazonaws.services.glacier.model.CompleteMultipartUploadResult;
import com.amazonaws.services.glacier.model.InitiateMultipartUploadRequest;
import com.amazonaws.services.glacier.model.InitiateMultipartUploadResult;
import com.amazonaws.services.glacier.model.UploadMultipartPartRequest;
import com.amazonaws.services.glacier.model.UploadMultipartPartResult;
import com.amazonaws.util.BinaryUtils;

public class ArchiveMPU {

    public static String vaultName = "examplevault";
    // This example works for part sizes up to 1 GB.
    public static String partSize = "1048576"; // 1 MB.
    public static String archiveFilePath = "*** provide archive file path ***";
    public static AmazonGlacierClient client;
    
    public static void main(String[] args) throws IOException {

    	ProfileCredentialsProvider credentials = new ProfileCredentialsProvider();

        client = new AmazonGlacierClient(credentials);
        client.setEndpoint("https://glacier.us-west-2.amazonaws.com/");

        try {
            System.out.println("Uploading an archive.");
            String uploadId = initiateMultipartUpload();
            String checksum = uploadParts(uploadId);
            String archiveId = CompleteMultiPartUpload(uploadId, checksum);
            System.out.println("Completed an archive. ArchiveId: " + archiveId);
            
        } catch (Exception e) {
            System.err.println(e);
        }

    }
    
    private static String initiateMultipartUpload() {
        // Initiate
        InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest()
            .withVaultName(vaultName)
            .withArchiveDescription("my archive " + (new Date()))
            .withPartSize(partSize);            
        
        InitiateMultipartUploadResult result = client.initiateMultipartUpload(request);
        
        System.out.println("ArchiveID: " + result.getUploadId());
        return result.getUploadId();
    }

    private static String uploadParts(String uploadId) throws AmazonServiceException, NoSuchAlgorithmException, AmazonClientException, IOException {

        int filePosition = 0;
        long currentPosition = 0;
        byte[] buffer = new byte[Integer.valueOf(partSize)];
        List<byte[]> binaryChecksums = new LinkedList<byte[]>();
        
        File file = new File(archiveFilePath);
        FileInputStream fileToUpload = new FileInputStream(file);
        String contentRange;
        int read = 0;
        while (currentPosition < file.length())
        {
            read = fileToUpload.read(buffer, filePosition, buffer.length);
            if (read == -1) { break; }
            byte[] bytesRead = Arrays.copyOf(buffer, read);

            contentRange = String.format("bytes %s-%s/*", currentPosition, currentPosition + read - 1);
            String checksum = TreeHashGenerator.calculateTreeHash(new ByteArrayInputStream(bytesRead));
            byte[] binaryChecksum = BinaryUtils.fromHex(checksum);
            binaryChecksums.add(binaryChecksum);
            System.out.println(contentRange);
                        
            //Upload part.
            UploadMultipartPartRequest partRequest = new UploadMultipartPartRequest()
            .withVaultName(vaultName)
            .withBody(new ByteArrayInputStream(bytesRead))
            .withChecksum(checksum)
            .withRange(contentRange)
            .withUploadId(uploadId);               
        
            UploadMultipartPartResult partResult = client.uploadMultipartPart(partRequest);
            System.out.println("Part uploaded, checksum: " + partResult.getChecksum());
            
            currentPosition = currentPosition + read;
        }
        fileToUpload.close();
        String checksum = TreeHashGenerator.calculateTreeHash(binaryChecksums);
        return checksum;
    }

    private static String CompleteMultiPartUpload(String uploadId, String checksum) throws NoSuchAlgorithmException, IOException {
        
        File file = new File(archiveFilePath);

        CompleteMultipartUploadRequest compRequest = new CompleteMultipartUploadRequest()
            .withVaultName(vaultName)
            .withUploadId(uploadId)
            .withChecksum(checksum)
            .withArchiveSize(String.valueOf(file.length()));
        
        CompleteMultipartUploadResult compResult = client.completeMultipartUpload(compRequest);
        return compResult.getLocation();
    }
}
```

# 使用上传大型档案 适用于 .NET 的 AWS SDK
<a name="uploading-an-archive-mpu-using-dotnet"></a>

适用于.NET 的 Amazon SDK APIs 提供的[高级和低级](using-aws-sdk.md)都提供了一种分段上传大型档案的方法（参见[在 Amazon Glacier 中上传档案](uploading-an-archive.md)）。

 
+ 该高级 API 提供了您可以用来上传任何大小的档案的方法。根据您要上传的文件，该方法会在单个操作中上传档案或者使用 Amazon Glacier（Amazon Glacier）中的分段上传支持来分段上传档案。
+ 该低级 API 紧密映射到底层 REST 实施。因此，它提供了一个在单个操作中上传较小档案的方法，以及一组支持较大档案的分段上传的方法。此部分说明了使用低级 API 分段上传大型档案的操作。

有关高级和低级别的更多信息 APIs，请参阅[将适用于 .NET 的 AWS SDK 与 Amazon Glacier 结合使用](using-aws-sdk-for-dot-net.md)。

**Topics**
+ [使用的高级别 API 分段上传大型档案 适用于 .NET 的 AWS SDK](#uploading-an-archive-in-parts-highlevel-using-dotnet)
+ [使用的低级 API 分段上传大型档案 适用于 .NET 的 AWS SDK](#uploading-an-archive-in-parts-lowlevel-using-dotnet)

## 使用的高级别 API 分段上传大型档案 适用于 .NET 的 AWS SDK
<a name="uploading-an-archive-in-parts-highlevel-using-dotnet"></a>

您可以使用高级 API 的相同方法上传小型或大型档案。根据档案大小，高级 API 方法会决定是在单个操作中上传档案，还是使用 Amazon Glacier 提供的分段上传 API 上传档案。有关更多信息，请参阅 [使用的高级别 API 上传档案 适用于 .NET 的 AWS SDK](uploading-an-archive-single-op-using-dotnet.md#uploading-an-archive-single-op-highlevel-using-dotnet)。

## 使用的低级 API 分段上传大型档案 适用于 .NET 的 AWS SDK
<a name="uploading-an-archive-in-parts-lowlevel-using-dotnet"></a>

对于上传的粒度控制，您可以使用低级 API（您可以在其中配置请求以及处理响应）。以下是使用 适用于 .NET 的 AWS SDK分段上传大型档案的步骤。

 

1. 创建 `AmazonGlacierClient` 类（客户端）的实例。

   您需要指定要保存档案的 AWS 区域。您使用此客户端执行的所有操作都适用于该 AWS 区域。

1. 通过调用 `InitiateMultipartUpload` 方法启动分段上传。

   您需要提供要上传档案的文件库名称、要上传的档案段的大小，也可选择提供相关描述。您可以通过创建 `InitiateMultipartUploadRequest` 类的实例提供此信息。作为响应，Amazon Glacier 会返回上传 ID。

1. 通过调用 `UploadMultipartPart` 方法上传段。

   对于要上传的每一段，您需要提供文件库名称、将在此段中上传的最终组合档案的字节范围、段数据的校验和，以及上传 ID。

1. 通过调用 `CompleteMultipartUpload` 方法完成分段上传。

   您需要提供上传 ID、整个档案的校验和、档案大小（您上传的所有段的组合大小）和文件库名称。Amazon Glacier 从上传的分段构造档案并返回档案 ID。

### 示例：使用适用于 .NET 的 Amazon SDK 分段上传大型档案
<a name="upload-archive-mpu-dotnet-example"></a>

以下 C\$1 代码示例使用将档案上传 适用于 .NET 的 AWS SDK 到文件库 (`examplevault`)。有关如何运行此示例的 step-by-step说明，请参阅[运行代码示例](using-aws-sdk-for-dot-net.md#setting-up-and-testing-sdk-dotnet)。您需要更新待上传文件名称旁显示的代码。

**Example**  

```
using System;
using System.Collections.Generic;
using System.IO;
using Amazon.Glacier;
using Amazon.Glacier.Model;
using Amazon.Runtime;

namespace glacier.amazon.com.rproxy.govskope.us.docsamples
{
  class ArchiveUploadMPU
  {
    static string vaultName       = "examplevault";
    static string archiveToUpload = "*** Provide file name (with full path) to upload ***";
    static long partSize          = 4194304; // 4 MB.

    public static void Main(string[] args)
    {
      AmazonGlacierClient client;
      List<string> partChecksumList = new List<string>();
      try
      {
         using (client = new AmazonGlacierClient(Amazon.RegionEndpoint.USWest2)) 
        {
          Console.WriteLine("Uploading an archive.");
          string uploadId  = InitiateMultipartUpload(client);
          partChecksumList = UploadParts(uploadId, client);
          string archiveId = CompleteMPU(uploadId, client, partChecksumList);
          Console.WriteLine("Archive ID: {0}", archiveId);
        }
        Console.WriteLine("Operations successful. To continue, press Enter");
        Console.ReadKey();
      }
      catch (AmazonGlacierException e) { Console.WriteLine(e.Message); }
      catch (AmazonServiceException e) { Console.WriteLine(e.Message); }
      catch (Exception e) { Console.WriteLine(e.Message); }
      Console.WriteLine("To continue, press Enter");
      Console.ReadKey();
    }

    static string InitiateMultipartUpload(AmazonGlacierClient client)
    {
      InitiateMultipartUploadRequest initiateMPUrequest = new InitiateMultipartUploadRequest()
      {

        VaultName = vaultName,
        PartSize = partSize,
        ArchiveDescription = "Test doc uploaded using MPU."
      };

      InitiateMultipartUploadResponse initiateMPUresponse = client.InitiateMultipartUpload(initiateMPUrequest);

      return initiateMPUresponse.UploadId;
    }

    static List<string> UploadParts(string uploadID, AmazonGlacierClient client)
    {
      List<string> partChecksumList = new List<string>();
      long currentPosition = 0;
      var buffer = new byte[Convert.ToInt32(partSize)];

      long fileLength = new FileInfo(archiveToUpload).Length;
      using (FileStream fileToUpload = new FileStream(archiveToUpload, FileMode.Open, FileAccess.Read))
      {
        while (fileToUpload.Position < fileLength)
        {
          Stream uploadPartStream = GlacierUtils.CreatePartStream(fileToUpload, partSize);
          string checksum = TreeHashGenerator.CalculateTreeHash(uploadPartStream);
          partChecksumList.Add(checksum);
          // Upload part.
          UploadMultipartPartRequest uploadMPUrequest = new UploadMultipartPartRequest()
          {

            VaultName = vaultName,
            Body = uploadPartStream,
            Checksum = checksum,
            UploadId = uploadID
          };
          uploadMPUrequest.SetRange(currentPosition, currentPosition + uploadPartStream.Length - 1);
          client.UploadMultipartPart(uploadMPUrequest);

          currentPosition = currentPosition + uploadPartStream.Length;
        }
      }
      return partChecksumList;
    }

    static string CompleteMPU(string uploadID, AmazonGlacierClient client, List<string> partChecksumList)
    {
      long fileLength = new FileInfo(archiveToUpload).Length;
      CompleteMultipartUploadRequest completeMPUrequest = new CompleteMultipartUploadRequest()
      {
        UploadId = uploadID,
        ArchiveSize = fileLength.ToString(),
        Checksum = TreeHashGenerator.CalculateTreeHash(partChecksumList),
        VaultName = vaultName
      };

      CompleteMultipartUploadResponse completeMPUresponse = client.CompleteMultipartUpload(completeMPUrequest);
      return completeMPUresponse.ArchiveId;
    }
  }
}
```

# 使用 REST API 分段上传大型档案
<a name="uploading-an-archive-mpu-using-rest"></a>

如[分段上传大型档案（分段上传）](uploading-archive-mpu.md)中所述，分段上传是指一组操作，这些操作可让您分段上传档案并执行相关操作。有关这些操作的更多信息，请参阅以下 API 参考主题：

 
+ [启动分段上传（POST multipart-uploads）](api-multipart-initiate-upload.md)
+ [上传段（PUT uploadID）](api-upload-part.md)
+ [完成分段上传（POST uploadID）](api-multipart-complete-upload.md)
+ [中止分段上传（DELETE uploadID）](api-multipart-abort-upload.md)
+ [列出段（GET uploadID）](api-multipart-list-parts.md)
+ [列出分段上传（GET multipart-uploads）](api-multipart-list-uploads.md)