此页面仅适用于使用文件库和 2012 年原始 REST API 的 S3 Glacier 服务的现有客户。
如果您正在寻找归档存储解决方案,建议使用 Amazon S3 中的 S3 Glacier 存储类 S3 Glacier Instant Retrieval、S3 Glacier Flexible Retrieval 和 S3 Glacier Deep Archive。要了解有关这些存储选项的更多信息,请参阅《Amazon S3 用户指南》中的 S3 Glacier 存储类
本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
使用适用于 Java 的 Amazon SDK 分段上传大型档案
适用于 Java 的 Amazon SDK APIs 提供的高级和低级都提供了一种上传大型档案的方法(参见在 Amazon S3 Glacier 中上传档案)。
-
该高级 API 提供了您可以用来上传任何大小的档案的方法。根据您要上传的文件,该方法会在单一操作中上传档案或者使用 Amazon S3 Glacier(S3 Glacier)中的分段上传支持来分段上传档案。
-
该低级 API 紧密映射到底层 REST 实施。因此,它提供了一个在单一操作中上传较小档案的方法,以及一组支持较大档案的分段上传的方法。此部分说明了使用低级 API 分段上传大型档案的操作。
有关高级和低级别的更多信息 APIs,请参阅适用于 Java 的 Amazon SDK 与 Amazon S3 Glacier 搭配使用。
使用的高级别 API 分段上传大型档案 适用于 Java 的 Amazon SDK
您可以使用高级 API 的相同方法上传小型或大型档案。根据档案大小,高级 API 方法会决定是在单个操作中上传档案,还是使用 S3 Glacier 提供的分段上传 API 上传档案。有关更多信息,请参阅 使用的高级别 API 上传档案 适用于 Java 的 Amazon SDK。
使用的低级 API 分段上传大型档案 适用于 Java 的 Amazon SDK
对于上传的粒度控制,您可以使用低级 API(您可以在其中配置请求以及处理响应)。以下是使用 适用于 Java 的 Amazon SDK分段上传大型档案的步骤。
-
创建
AmazonGlacierClient
类(客户端)的实例。您需要指定要保存档案的 Amazon 区域。您使用此客户端执行的所有操作都适用于该 Amazon 区域。
-
通过调用
initiateMultipartUpload
方法启动分段上传。您需要提供要上传档案的文件库名称、要上传的档案段的大小,也可选择提供相关描述。您可以通过创建
InitiateMultipartUploadRequest
类的实例提供此信息。作为响应,S3 Glacier 会返回上传 ID。 -
通过调用
uploadMultipartPart
方法上传段。对于要上传的每一段,您需要提供文件库名称、将在此段中上传的最终组合档案的字节范围、段数据的校验和,以及上传 ID。
-
通过调用
completeMultipartUpload
方法完成分段上传。您需要提供上传 ID、整个档案的校验和、档案大小(您上传的所有段的组合大小)和文件库名称。S3 Glacier 从上传的分段构造档案并返回档案 ID。
示例:使用分段上传大型档案 适用于 Java 的 Amazon SDK
以下 Java 代码示例使用将档案上传 适用于 Java 的 Amazon SDK 到文件库 (examplevault
)。有关如何运行此示例的 step-by-step说明,请参阅使用 Eclipse 运行 Amazon S3 Glacier 的 Java 示例。您需要更新待上传文件名称旁所显示的代码。
注意
此示例对 1MB 到 1GB 的段大小有效。但是,S3 Glacier 支持最大为 4GB 的分段。
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(); } }