Amazon Simple Storage Service
开发人员指南 (API 版本 2006-03-01)
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 Amazon AWS 入门

使用AWS SDK for Java分段上传 API 复制对象

要使用AWS SDK for Java复制大于 5 GB 的 Amazon S3 对象,请使用低级别 Java API。对于小于 5 GB 的对象,请使用使用 AWS SDK for Java 复制对象中所述的单个操作复制。

要使用低级别 Java API 复制对象,请执行以下操作:

  • 通过执行 AmazonS3Client.initiateMultipartUpload() 方法启动分段上传。

  • AmazonS3Client.initiateMultipartUpload() 方法返回的响应对象保存上传 ID。您为每个分段上传操作提供此上传 ID。

  • 复制所有段。对于需要复制的每个段,创建一个 CopyPartRequest 类的新实例。提供段信息,包括源和目标存储桶名称、源和目标对象键、上传 ID、段的第一个字节和最后一个字节的位置以及段编号。

  • 保存 AmazonS3Client.copyPart() 方法调用的响应。每个响应均包括 ETag 值和已上传分段的段编号。您需要此信息才能完成分段上传。

  • 调用 AmazonS3Client.completeMultipartUpload() 方法以完成复制操作。

以下示例说明如何使用 Amazon S3 低级别 Java API 执行分段复制。有关创建和测试有效示例的说明,请参阅测试 Amazon S3 Java 代码示例

import java.io.IOException; import java.util.ArrayList; import java.util.List; import com.amazonaws.AmazonServiceException; import com.amazonaws.SdkClientException; import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.services.s3.*; import com.amazonaws.services.s3.model.*; public class LowLevelMultipartCopy { public static void main(String[] args) throws IOException { String clientRegion = "*** Client region ***"; String sourceBucketName = "*** Source bucket name ***"; String sourceObjectKey = "*** Source object key ***"; String destBucketName = "*** Target bucket name ***"; String destObjectKey = "*** Target object key ***"; try { AmazonS3 s3Client = AmazonS3ClientBuilder.standard() .withCredentials(new ProfileCredentialsProvider()) .withRegion(clientRegion) .build(); // Initiate the multipart upload. InitiateMultipartUploadRequest initRequest = new InitiateMultipartUploadRequest(destBucketName, destObjectKey); InitiateMultipartUploadResult initResult = s3Client.initiateMultipartUpload(initRequest); // Get the object size to track the end of the copy operation. GetObjectMetadataRequest metadataRequest = new GetObjectMetadataRequest(sourceBucketName, sourceObjectKey); ObjectMetadata metadataResult = s3Client.getObjectMetadata(metadataRequest); long objectSize = metadataResult.getContentLength(); // Copy the object using 5 MB parts. long partSize = 5 * 1024 * 1024; long bytePosition = 0; int partNum = 1; List<CopyPartResult> copyResponses = new ArrayList<CopyPartResult>(); while (bytePosition < objectSize) { // The last part might be smaller than partSize, so check to make sure // that lastByte isn't beyond the end of the object. long lastByte = Math.min(bytePosition + partSize - 1, objectSize - 1); // Copy this part. CopyPartRequest copyRequest = new CopyPartRequest() .withSourceBucketName(sourceBucketName) .withSourceKey(sourceObjectKey) .withDestinationBucketName(destBucketName) .withDestinationKey(destObjectKey) .withUploadId(initResult.getUploadId()) .withFirstByte(bytePosition) .withLastByte(lastByte) .withPartNumber(partNum++); copyResponses.add(s3Client.copyPart(copyRequest)); bytePosition += partSize; } // Complete the upload request to concatenate all uploaded parts and make the copied object available. CompleteMultipartUploadRequest completeRequest = new CompleteMultipartUploadRequest( destBucketName, destObjectKey, initResult.getUploadId(), getETags(copyResponses)); s3Client.completeMultipartUpload(completeRequest); System.out.println("Multipart copy complete."); } catch(AmazonServiceException e) { // The call was transmitted successfully, but Amazon S3 couldn't process // it, so it returned an error response. e.printStackTrace(); } catch(SdkClientException e) { // Amazon S3 couldn't be contacted for a response, or the client // couldn't parse the response from Amazon S3. e.printStackTrace(); } } // This is a helper function to construct a list of ETags. private static List<PartETag> getETags(List<CopyPartResult> responses) { List<PartETag> etags = new ArrayList<PartETag>(); for (CopyPartResult response : responses) { etags.add(new PartETag(response.getPartNumber(), response.getETag())); } return etags; } }