使用 Amazon S3 Transfer Manager 传输文件和目录 - Amazon SDK for Java 2.x
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

使用 Amazon S3 Transfer Manager 传输文件和目录

Amazon S3 Transfer Manager 是针对 Amazon SDK for Java 2.x的一款开源高级文件传输工具。可以使用它将文件和目录传入和传出 Amazon Simple Storage Service (Amazon S3)。

基于Amazon CRT 的 S3 客户端基础上构建时,S3 Transfer Manager 可以利用分段上传 API字节范围提取等性能改进。

使用 S3 Transfer Manager,您还可以实时监控传输进度,并暂停传输以便日后执行。

开始使用

将依赖项添加到构建文件中

要使用基于基于 Amazon CRT 的 S3 客户端的性能增强的 S3 传输管理器,请使用以下依赖项配置您的构建文件。

  • 使用适用于 Java 的 SDK 2.x 的 2.19.1 或更高版本。

  • s3-transfer-manager 构件添加为依赖项。

  • 0.20.3 或更高版本中,将 aws-crt 构件添加为依赖项。

以下代码示例演示如何为 Maven 配置项目依赖项。

<project> <properties> <aws.sdk.version>2.19.1</aws.sdk.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>bom</artifactId> <version>${aws.sdk.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>s3-transfer-manager</artifactId> </dependency> <dependency> <groupId>software.amazon.awssdk.crt</groupId> <artifactId>aws-crt</artifactId> <version>0.20.3</version> </dependency> </dependencies> </project>

在 Maven Central 存储库中搜索 s3-transfer-manageraws-crt 构件的最新版本。

创建 S3 Transfer Manager 的实例

以下代码段显示了如何使用默认设置创建 S3 TransferManager 实例。

S3TransferManager transferManager = S3TransferManager.create();

以下示例演示如何使用自定义设置来配置 S3 Transfer Manager。在此示例中,Amazon 基于 CRT 的 S3 AsyncClient 实例用作 S3 传输管理器的底层客户端。

S3AsyncClient s3AsyncClient = S3AsyncClient.crtBuilder() .credentialsProvider(DefaultCredentialsProvider.create()) .region(Region.US_EAST_1) .targetThroughputInGbps(20.0) .minimumPartSizeInBytes(8 * MB) .build(); S3TransferManager transferManager = S3TransferManager.builder() .s3Client(s3AsyncClient) .build();
注意

如果构建文件中未包含 aws-crt 依赖项,则 S3 Transfer Manager 将在适用于 Java 的 SDK 2.x 中使用的标准 S3 异步客户端的基础上构建。

将文件上传到 S3 桶

以下示例显示了文件上传示例 LoggingTransferListener,以及记录上传进度的可选用法。

要使用 S3 Transfer Manager 将文件上传到 Amazon S3,请将 UploadFileRequest 对象传递给 S3TransferManageruploadFile 方法。

从该uploadFile方法返回的FileUpload对象表示上传过程。请求完成后,该CompletedFileUpload对象将包含有关上传的信息。

public String uploadFile(S3TransferManager transferManager, String bucketName, String key, URI filePathURI) { UploadFileRequest uploadFileRequest = UploadFileRequest.builder() .putObjectRequest(b -> b.bucket(bucketName).key(key)) .source(Paths.get(filePathURI)) .build(); FileUpload fileUpload = transferManager.uploadFile(uploadFileRequest); CompletedFileUpload uploadResult = fileUpload.completionFuture().join(); return uploadResult.response().eTag(); }
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import software.amazon.awssdk.transfer.s3.S3TransferManager; import software.amazon.awssdk.transfer.s3.model.CompletedFileUpload; import software.amazon.awssdk.transfer.s3.model.FileUpload; import software.amazon.awssdk.transfer.s3.model.UploadFileRequest; import software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Paths; import java.util.UUID;

从 S3 桶下载文件

以下示例显示了下载示例以及记录下载进度的可选用法。LoggingTransferListener

要使用 S3 传输管理器从 S3 存储桶下载对象,请生成一个DownloadFileRequest对象并将其传递给 downloadFile 方法。

downloadFile方法返回S3TransferManagerFileDownload对象表示文件传输。下载完成后,CompletedFileDownload包含对下载相关信息的访问权限。

public Long downloadFile(S3TransferManager transferManager, String bucketName, String key, String downloadedFileWithPath) { DownloadFileRequest downloadFileRequest = DownloadFileRequest.builder() .getObjectRequest(b -> b.bucket(bucketName).key(key)) .destination(Paths.get(downloadedFileWithPath)) .build(); FileDownload downloadFile = transferManager.downloadFile(downloadFileRequest); CompletedFileDownload downloadResult = downloadFile.completionFuture().join(); logger.info("Content length [{}]", downloadResult.response().contentLength()); return downloadResult.response().contentLength(); }
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import software.amazon.awssdk.core.sync.RequestBody; import software.amazon.awssdk.transfer.s3.S3TransferManager; import software.amazon.awssdk.transfer.s3.model.CompletedFileDownload; import software.amazon.awssdk.transfer.s3.model.DownloadFileRequest; import software.amazon.awssdk.transfer.s3.model.FileDownload; import software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener; import java.io.IOException; import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.UUID;

将 Amazon S3 对象复制到另一个桶。

以下示例演示如何使用 S3 Transfer Manager 复制对象。

要开始将对象从 S3 存储桶复制到另一个存储桶,请创建一个基本CopyObjectRequest实例。

接下来,将基本内容封装CopyObjectRequest在 S3 传输管理器可以使用的文件中。CopyRequest

S3TransferManagercopy 方法返回的 Copy 对象表示复制进程。复制过程完成后,该CompletedCopy对象将包含有关响应的详细信息。

public String copyObject(S3TransferManager transferManager, String bucketName, String key, String destinationBucket, String destinationKey) { CopyObjectRequest copyObjectRequest = CopyObjectRequest.builder() .sourceBucket(bucketName) .sourceKey(key) .destinationBucket(destinationBucket) .destinationKey(destinationKey) .build(); CopyRequest copyRequest = CopyRequest.builder() .copyObjectRequest(copyObjectRequest) .build(); Copy copy = transferManager.copy(copyRequest); CompletedCopy completedCopy = copy.completionFuture().join(); return completedCopy.response().copyObjectResult().eTag(); }
注意

要使用 S3 传输管理器执行跨区域复制,请在 Amazon 基于 CRT 的 S3 客户端生成器crossRegionAccessEnabled上启用,如以下代码段所示。

S3AsyncClient s3AsyncClient = S3AsyncClient.crtBuilder() .crossRegionAccessEnabled(true) .build(); S3TransferManager transferManager = S3TransferManager.builder() .s3Client(s3AsyncClient) .build();
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import software.amazon.awssdk.core.sync.RequestBody; import software.amazon.awssdk.services.s3.model.CopyObjectRequest; import software.amazon.awssdk.transfer.s3.S3TransferManager; import software.amazon.awssdk.transfer.s3.model.CompletedCopy; import software.amazon.awssdk.transfer.s3.model.Copy; import software.amazon.awssdk.transfer.s3.model.CopyRequest; import java.util.UUID;

将本地目录上传到 S3 桶

以下示例演示如何将本地目录上传到 S3。

首先调用S3TransferManager实例的 uploadDirectory 方法,传入。UploadDirectoryRequest

DirectoryUpload对象表示上传过程,该过程会在请求完成CompletedDirectoryUpload时生成。CompleteDirectoryUpload 对象包含有关传输结果的信息,包括哪些文件传输失败。

public Integer uploadDirectory(S3TransferManager transferManager, URI sourceDirectory, String bucketName) { DirectoryUpload directoryUpload = transferManager.uploadDirectory(UploadDirectoryRequest.builder() .source(Paths.get(sourceDirectory)) .bucket(bucketName) .build()); CompletedDirectoryUpload completedDirectoryUpload = directoryUpload.completionFuture().join(); completedDirectoryUpload.failedTransfers() .forEach(fail -> logger.warn("Object [{}] failed to transfer", fail.toString())); return completedDirectoryUpload.failedTransfers().size(); }
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import software.amazon.awssdk.services.s3.model.ObjectIdentifier; import software.amazon.awssdk.transfer.s3.S3TransferManager; import software.amazon.awssdk.transfer.s3.model.CompletedDirectoryUpload; import software.amazon.awssdk.transfer.s3.model.DirectoryUpload; import software.amazon.awssdk.transfer.s3.model.UploadDirectoryRequest; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Paths; import java.util.UUID;

将 S3 桶对象下载到本地目录

您可以将 S3 桶中的对象下载到本地目录,如以下示例所示。

要将 S3 存储桶中的对象下载到本地目录,请首先调用传输管理器的 downloadDirectory 方法,传入。DownloadDirectoryRequest

DirectoryDownload对象表示下载过程,该过程会在请求完成CompletedDirectoryDownload时生成。CompleteDirectoryDownload 对象包含有关传输结果的信息,包括哪些文件传输失败。

public Integer downloadObjectsToDirectory(S3TransferManager transferManager, URI destinationPathURI, String bucketName) { DirectoryDownload directoryDownload = transferManager.downloadDirectory(DownloadDirectoryRequest.builder() .destination(Paths.get(destinationPathURI)) .bucket(bucketName) .build()); CompletedDirectoryDownload completedDirectoryDownload = directoryDownload.completionFuture().join(); completedDirectoryDownload.failedTransfers() .forEach(fail -> logger.warn("Object [{}] failed to transfer", fail.toString())); return completedDirectoryDownload.failedTransfers().size(); }
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import software.amazon.awssdk.core.sync.RequestBody; import software.amazon.awssdk.services.s3.model.ObjectIdentifier; import software.amazon.awssdk.transfer.s3.S3TransferManager; import software.amazon.awssdk.transfer.s3.model.CompletedDirectoryDownload; import software.amazon.awssdk.transfer.s3.model.DirectoryDownload; import software.amazon.awssdk.transfer.s3.model.DownloadDirectoryRequest; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.HashSet; import java.util.Set; import java.util.UUID; import java.util.stream.Collectors;

查看完整示例

GitHub 包含本页上所有示例的完整代码。