使用 Amazon S3 Transfer Manager 传输文件和目录 - AWS SDK for Java 2.x

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

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

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

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

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

开始使用

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

要在使用 S3 Transfer Manager 时获得增强的分段性能,请使用必要的依赖项配置构建文件。

Use the AWS CRT-based S3 client
<dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>bom</artifactId> <version>2.27.211</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.29.1432</version> </dependency> </dependencies>

1 最新版本2最新版本

Use the Java-based S3 async client
<dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>bom</artifactId> <version>2.27.211</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>s3-transfer-manager</artifactId> </dependency> </dependencies>

1 最新版本

创建 S3 Transfer Manager 的实例

要启用并行传输,必须传入 AWS 基于 CRT 的 S3 客户端或启用了多部分功能的基于 Java 的 S3 异步客户端。以下示例演示如何使用自定义设置来配置 S3 Transfer Manager。

Use the AWS CRT-based S3 client
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();
Use the Java-based S3 async client

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

S3 客户端的自定义配置 - 需要启用分段功能

S3AsyncClient s3AsyncClient = S3AsyncClient.builder() .multipartEnabled(true) .credentialsProvider(DefaultCredentialsProvider.create()) .region(Region.US_EAST_1) .build(); S3TransferManager transferManager = S3TransferManager.builder() .s3Client(s3AsyncClient) .build();

没有 S3 客户端配置 - 自动启用分段支持

S3TransferManager transferManager = S3TransferManager.create();

将文件上传到 S3 桶

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

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

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

public void trackUploadFile(S3TransferManager transferManager, String bucketName, String key, URI filePathURI) { UploadFileRequest uploadFileRequest = UploadFileRequest.builder() .putObjectRequest(b -> b.bucket(bucketName).key(key)) .addTransferListener(LoggingTransferListener.create()) // Add listener. .source(Paths.get(filePathURI)) .build(); FileUpload fileUpload = transferManager.uploadFile(uploadFileRequest); fileUpload.completionFuture().join(); /* The SDK provides a LoggingTransferListener implementation of the TransferListener interface. You can also implement the interface to provide your own logic. Configure log4J2 with settings such as the following. <Configuration status="WARN"> <Appenders> <Console name="AlignedConsoleAppender" target="SYSTEM_OUT"> <PatternLayout pattern="%m%n"/> </Console> </Appenders> <Loggers> <logger name="software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener" level="INFO" additivity="false"> <AppenderRef ref="AlignedConsoleAppender"/> </logger> </Loggers> </Configuration> Log4J2 logs the progress. The following is example output for a 21.3 MB file upload. Transfer initiated... | | 0.0% |==== | 21.1% |============ | 60.5% |====================| 100.0% Transfer complete! */ }
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 void trackDownloadFile(S3TransferManager transferManager, String bucketName, String key, String downloadedFileWithPath) { DownloadFileRequest downloadFileRequest = DownloadFileRequest.builder() .getObjectRequest(b -> b.bucket(bucketName).key(key)) .addTransferListener(LoggingTransferListener.create()) // Add listener. .destination(Paths.get(downloadedFileWithPath)) .build(); FileDownload downloadFile = transferManager.downloadFile(downloadFileRequest); CompletedFileDownload downloadResult = downloadFile.completionFuture().join(); /* The SDK provides a LoggingTransferListener implementation of the TransferListener interface. You can also implement the interface to provide your own logic. Configure log4J2 with settings such as the following. <Configuration status="WARN"> <Appenders> <Console name="AlignedConsoleAppender" target="SYSTEM_OUT"> <PatternLayout pattern="%m%n"/> </Console> </Appenders> <Loggers> <logger name="software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener" level="INFO" additivity="false"> <AppenderRef ref="AlignedConsoleAppender"/> </logger> </Loggers> </Configuration> Log4J2 logs the progress. The following is example output for a 21.3 MB file download. Transfer initiated... |======= | 39.4% |=============== | 78.8% |====================| 100.0% Transfer complete! */ }
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import software.amazon.awssdk.core.exception.SdkException; 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.NoSuchFileException; 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 传输管理器执行跨区域复制,请在 AWS 基于 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 包含本页上所有示例的完整代码。