跨AWS账号复制S3对象如何直接基于S3Object完成上传操作?
跨AWS账号S3对象复制方案说明
方案1:基于已获取的S3Object直接流式上传
你当前拿到的S3Object实例本身内置getObjectContent()方法,可以直接返回S3ObjectInputStream类型的输入流,完全可以直接传入putObject接口,不需要把对象全量加载到内存或写入本地文件做中转,属于边下载边上传的流式处理,不会占用额外本地存储:
// 从源端S3Object获取输入流 try (S3ObjectInputStream sourceStream = s3object.getObjectContent()) { // 构造目标端上传请求,直接传入输入流和对象元数据 PutObjectRequest putRequest = PutObjectRequest.builder() .bucket(targetBucket) .key(targetKey) .contentLength(s3object.getObjectMetadata().getContentLength()) .build(); targetClient.putObject(putRequest, RequestBody.fromInputStream(sourceStream, s3object.getObjectMetadata().getContentLength())); }
注意:必须显式传入对象的ContentLength元数据,否则S3客户端会默认先缓存全量流数据到内存来计算内容长度,反而会造成内存占用过高的问题,处理大对象时尤其要注意。
方案2:更推荐的跨账号复制方案(完全无本地中转)
不需要先调用getObject下载对象到本地再上传,AWS S3原生提供CopyObject接口,支持直接在AWS服务端完成跨账号的对象复制,全程不会占用你本地的带宽和计算资源,仅需要给对应账号配置好跨账号访问权限即可:
- 权限配置要求:源端Bucket策略要授权目标账号的IAM身份有
s3:GetObject权限,目标端Bucket策略要授权当前操作身份有s3:PutObject权限 - 代码示例:
CopyObjectRequest copyRequest = CopyObjectRequest.builder() .sourceBucket(sourceBucket) .sourceKey(sourceKey) .destinationBucket(targetBucket) .destinationKey(targetKey) // 跨账号场景需要显式指定源端所属账号ID,避免权限校验失败 .expectedSourceBucketOwner(sourceAccountId) .expectedDestinationBucketOwner(targetAccountId) .build(); targetClient.copyObject(copyRequest);
如果是大于5GB的大对象,建议改用CopyPart分块复制接口,避免单请求超时失败。
内容的提问来源于stack exchange,提问作者Kaushik Karalgikar
相关产品推荐
相关产品推荐

