將 Transfer Manager 從 第 1 版遷移至 第 2 版 適用於 Java 的 AWS SDK - AWS SDK for Java 2.x

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

將 Transfer Manager 從 第 1 版遷移至 第 2 版 適用於 Java 的 AWS SDK

此遷移指南涵蓋 Transfer Manager v1 和 S3 Transfer Manager v2 之間的主要差異,包括建構函數變更、方法映射和常見操作的程式碼範例。檢閱這些差異後,您可以成功遷移現有的 Transfer Manager 程式碼,以利用 v2 中改善的效能和非同步操作。

關於 AWS SDK 遷移工具

適用於 Java 的 AWS SDK 提供自動化遷移工具,可將大部分 v1 Transfer Manager API 遷移至 v2。不過,遷移工具不支援數個 v1 Transfer Manager 功能。在這些情況下,您需要使用本主題中的指引手動遷移 Transfer Manager 程式碼。

在本指南中,遷移狀態指示燈會顯示遷移工具是否可以自動遷移建構函數、方法或功能:

  • ✅ 支援:遷移工具可以自動轉換此程式碼

  • ❌ 不支援:您需要手動遷移程式碼

即使是標記為「支援」的項目,請檢閱遷移結果並徹底測試。Transfer Manager 遷移涉及從同步操作到非同步操作的重大架構變更。

概觀

S3 Transfer Manager v2 會將重大變更引入 Transfer Manager API。S3 Transfer Manager v2 建立在非同步操作上,並提供更好的效能,尤其是當您使用 AWS CRT 型 Amazon S3 用戶端時。

主要差異

  • 套件com.amazonaws.services.s3.transfersoftware.amazon.awssdk.transfer.s3

  • 類別名稱TransferManagerS3TransferManager

  • 用戶端相依性:同步 Amazon S3 用戶端 → 非同步 Amazon S3 用戶端 (S3AsyncClient)

  • 架構:同步操作 → 使用 進行非同步操作 CompletableFuture

  • 效能:透過 AWS CRT 型用戶端支援增強

高階變更

Aspect V1 V2
Maven 相依性 aws-java-sdk-s3 s3-transfer-manager
套件 com.amazonaws.services.s3.transfer software.amazon.awssdk.transfer.s3
主要類別 TransferManager S3TransferManager
Amazon S3 用戶端 AmazonS3 (同步) S3AsyncClient (非同步)
傳回類型 封鎖操作 CompletableFuture<T>

Maven 相依性

V1 V2
<dependencyManagement> <dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-java-sdk-bom</artifactId> <version>>1.12.7871</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-java-sdk-s3</artifactId> </dependency> </dependencies>
<dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>bom</artifactId> <version>2.31.682</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>s3-transfer-manager</artifactId> </dependency> <!-- Optional: For enhanced performance with AWS CRT --> <dependency> <groupId>software.amazon.awssdk.crt</groupId> <artifactId>aws-crt</artifactId> <version>0.38.53</version> </dependency> </dependencies>

1 最新版本。 2 最新版本。 3最新版本

用戶端建構函數遷移

支援的建構函數 (自動遷移)

V1 建構函數 V2 對等 遷移狀態
new TransferManager() S3TransferManager.create() ✅ 支援的
TransferManagerBuilder. defaultTransferManager() S3TransferManager.create() ✅ 支援的
TransferManagerBuilder. standard().build() S3TransferManager.builder().build() ✅ 支援的
new TransferManager(AWSCredentials) S3TransferManager.builder() .s3Client(S3AsyncClient.builder() .credentialsProvider(...).build()) .build() ✅ 支援的
new TransferManager( AWSCredentialsProvider) S3TransferManager.builder() .s3Client(S3AsyncClient.builder() .credentialsProvider(...).build()) .build() ✅ 支援的

不支援的建構函數 (需要手動遷移)

V1 建構函數 V2 對等 遷移備註
new TransferManager(AmazonS3) 需要手動遷移 S3AsyncClient 分別建立
new TransferManager(AmazonS3, ExecutorService) 需要手動遷移 建立 S3AsyncClient並設定執行器
new TransferManager(AmazonS3, ExecutorService, boolean) 需要手動遷移 shutDownThreadPools 不支援 參數

手動遷移範例

V1 程式碼:

AmazonS3 s3Client = AmazonS3ClientBuilder.defaultClient(); TransferManager transferManager = new TransferManager(s3Client);

V2 程式碼:

// Create an `S3AsyncClient` with similar configuration S3AsyncClient s3AsyncClient = S3AsyncClient.builder() .credentialsProvider(DefaultCredentialsProvider.create()) .build(); // Provide the configured `S3AsyncClient` to the S3 transfer manager builder. S3TransferManager transferManager = S3TransferManager.builder() .s3Client(s3AsyncClient) .build();

用戶端方法遷移

目前,遷移工具支援基本 copydownloaduploaduploadDirectorydownloadDirectoryresumeDownloadresumeUpload方法。

核心傳輸方法

V1 方法 V2 方法 傳回類型變更 遷移狀態
upload(String, String, File) uploadFile(UploadFileRequest) UploadFileUpload ✅ 支援的
upload(PutObjectRequest) upload(UploadRequest) UploadUpload ✅ 支援的
download(String, String, File) downloadFile(DownloadFileRequest) DownloadFileDownload ✅ 支援的
download(GetObjectRequest, File) downloadFile(DownloadFileRequest) DownloadFileDownload ✅ 支援的
copy(String, String, String, String) copy(CopyRequest) CopyCopy ✅ 支援的
copy(CopyObjectRequest) copy(CopyRequest) CopyCopy ✅ 支援的
uploadDirectory(String, String, File, boolean) uploadDirectory( UploadDirectoryRequest) MultipleFileUploadDirectoryUpload ✅ 支援的
downloadDirectory(String, String, File) downloadDirectory( DownloadDirectoryRequest) MultipleFileDownloadDirectoryDownload ✅ 支援的

可繼續傳輸方法

V1 方法 V2 方法 遷移狀態
resumeUpload(PersistableUpload) resumeUploadFile(ResumableFileUpload) ✅ 支援的
resumeDownload(PersistableDownload) resumeDownloadFile(ResumableFileDownload) ✅ 支援的

生命週期方法

V1 方法 V2 方法 遷移狀態
shutdownNow() close() ✅ 支援的
shutdownNow(boolean) 使用 close()方法手動調整程式碼 ❌ 不支援

不支援的 V1 用戶端方法

V1 方法 V2 替代方案 備註
abortMultipartUploads(String, Date) 使用低階 Amazon S3 用戶端 ❌ 不支援
getAmazonS3Client() 分別儲存參考 ❌ 不支援;v2 中沒有 getter
getConfiguration() 分別儲存參考 ❌ 不支援;v2 中沒有 getter
uploadFileList(...) 進行多次uploadFile()呼叫 ❌ 不支援
copy 具有 TransferStateChangeListener 參數的方法 使用 TransferListener 請參閱手動遷移範例
download 方法搭配 S3ProgressListener 參數 使用 TransferListener 請參閱手動遷移範例

downloadDirectory 具有 4 個或更多參數的方法

請參閱手動遷移範例
upload 方法與 ObjectMetadataProvider 參數 在請求中設定中繼資料 請參閱手動遷移範例
uploadDirectory 方法與 *Provider 參數 在請求中設定標籤 請參閱手動遷移範例

copy 具有 TransferStateChangeListener 參數的方法

  • copy(CopyObjectRequest copyObjectRequest, AmazonS3 srcS3, TransferStateChangeListener stateChangeListener)

  • copy(CopyObjectRequest copyObjectRequest, TransferStateChangeListener stateChangeListener)

// V1 ---------------------------------------------------------------------------------------------- // Initialize source S3 client AmazonS3 s3client = AmazonS3ClientBuilder.standard() .withRegion("us-west-2") .build(); // Initialize Transfer Manager TransferManager tm = TransferManagerBuilder.standard() .withS3Client(srcS3) .build(); CopyObjectRequest copyObjectRequest = new CopyObjectRequest( "amzn-s3-demo-source-bucket", "source-key", "amzn-s3-demo-destination-bucket", "destination-key" ); TransferStateChangeListener stateChangeListener = new TransferStateChangeListener() { @Override public void transferStateChanged(Transfer transfer, TransferState state) { //Implementation of the TransferStateChangeListener } }; Copy copy = tm.copy(copyObjectRequest, srcS3, stateChangeListener); // V2 ---------------------------------------------------------------------------------------------- S3AsyncClient s3AsyncClient = S3AsyncClient.builder() .region(Region.US_WEST_2) .build(); S3TransferManager transferManager = S3TransferManager.builder() .s3Client(s3AsyncClient) .build(); // Create transfer listener (equivalent to TransferStateChangeListener in v1) TransferListener transferListener = new TransferListener() { @Override public void transferInitiated(Context.TransferInitiated context) { //Implementation System.out.println("Transfer initiated"); } @Override public void bytesTransferred(Context.BytesTransferred context) { //Implementation System.out.println("Bytes transferred"); } @Override public void transferComplete(Context.TransferComplete context) { //Implementation System.out.println("Transfer completed!"); } @Override public void transferFailed(Context.TransferFailed context) { //Implementation System.out.println("Transfer failed"); } }; CopyRequest copyRequest = CopyRequest.builder() .copyObjectRequest(req -> req .sourceBucket("amzn-s3-demo-source-bucket") .sourceKey("source-key") .destinationBucket("amzn-s3-demo-destination-bucket") .destinationKey("destination-key") ) .addTransferListener(transferListener) // Configure the transferListener into the request .build(); Copy copy = transferManager.copy(copyRequest);

download 方法搭配 S3ProgressListener 參數

  • download(GetObjectRequest getObjectRequest, File file, S3ProgressListener progressListener)

  • download(GetObjectRequest getObjectRequest, File file, S3ProgressListener progressListener, long timeoutMillis)

  • download(GetObjectRequest getObjectRequest, File file, S3ProgressListener progressListener, long timeoutMillis, boolean resumeOnRetry)

// V1 ---------------------------------------------------------------------------------------------- S3ProgressListener progressListener = new S3ProgressListener() { @Override public void progressChanged(com.amazonaws.event.ProgressEvent progressEvent) { long bytes = progressEvent.getBytesTransferred(); ProgressEventType eventType = progressEvent.getEventType(); // Use bytes and eventType as needed } @Override public void onPersistableTransfer(PersistableTransfer persistableTransfer) { } }; Download download1 = tm.download(getObjectRequest, file, progressListener); Download download2 = tm.download(getObjectRequest, file, progressListener, timeoutMillis) Download download3 = tm.download(getObjectRequest, file, progressListener, timeoutMillis, true) // V2 ---------------------------------------------------------------------------------------------- TransferListener transferListener = new TransferListener() { @Override public void transferInitiated(Context.InitializedContext context) { // Equivalent to ProgressEventType.TRANSFER_STARTED_EVENT System.out.println("Transfer initiated"); } @Override public void bytesTransferred(Context.BytesTransferred context) { // Equivalent to ProgressEventType.REQUEST_BYTE_TRANSFER_EVENT long bytes = context.bytesTransferred(); System.out.println("Bytes transferred: " + bytes); } @Override public void transferComplete(Context.TransferComplete context) { // Equivalent to ProgressEventType.TRANSFER_COMPLETED_EVENT System.out.println("Transfer completed"); } @Override public void transferFailed(Context.TransferFailed context) { // Equivalent to ProgressEventType.TRANSFER_FAILED_EVENT System.out.println("Transfer failed: " + context.exception().getMessage()); } }; DownloadFileRequest downloadFileRequest = DownloadFileRequest.builder() .getObjectRequest(getObjectRequest) .destination(file.toPath()) .addTransferListener(transferListener) .build(); // For download1 FileDownload download = transferManager.downloadFile(downloadFileRequest); // For download2 CompletedFileDownload completedFileDownload = download.completionFuture() .get(timeoutMillis, TimeUnit.MILLISECONDS); // For download3, the v2 SDK does not have a direct equiavalent to the `resumeOnRetry` method of v1. // If a download is interrupted, you need to start a new download request.

downloadDirectory 具有 4 個或更多參數的方法

  • downloadDirectory(String bucketName, String keyPrefix, File destinationDirectory, boolean resumeOnRetry)

  • downloadDirectory(String bucketName, String keyPrefix, File destinationDirectory, boolean resumeOnRetry, KeyFilter filter)

  • downloadDirectory(String bucketName, String keyPrefix, File destinationDirectory, KeyFilter filter)

// V1 ---------------------------------------------------------------------------------------------- KeyFilter filter = new KeyFilter() { @Override public boolean shouldInclude(S3ObjectSummary objectSummary) { //Filter implementation } }; MultipleFileDownload multipleFileDownload = tm.downloadDirectory(bucketName, keyPrefix, destinationDirectory, filter); // V2 ---------------------------------------------------------------------------------------------- // The v2 SDK does not have a direct equiavalent to the `resumeOnRetry` method of v1. // If a download is interrupted, you need to start a new download request. DownloadFilter filter = new DownloadFilter() { @Override public boolean test(S3Object s3Object) { // Filter implementation. } }; DownloadDirectoryRequest downloadDirectoryRequest = DownloadDirectoryRequest.builder() .bucket(bucketName) .filter(filter) .listObjectsV2RequestTransformer(builder -> builder.prefix(keyPrefix)) .destination(destinationDirectory.toPath()) .build(); DirectoryDownload directoryDownload = transferManager.downloadDirectory(downloadDirectoryRequest);

upload 方法與 ObjectMetadata 參數

  • upload(String bucketName, String key, InputStream input, ObjectMetadata objectMetadata)

// V1 ----------------------------------------------------------------------------------------------ObjectMetadata metadata = new ObjectMetadata(); ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentType("text/plain"); // System-defined metadata metadata.setContentLength(22L); // System-defined metadata metadata.addUserMetadata("myKey", "myValue"); // User-defined metadata PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, inputStream, metadata); Upload upload = transferManager.upload("amzn-s3-demo-bucket", "my-key", inputStream, metadata); // V2 ---------------------------------------------------------------------------------------------- /* When you use an InputStream to upload in V2, you should specify the content length and use `RequestBody.fromInputStream()`. If you don't provide the content length, the entire stream will be buffered in memory. If you can't determine the content length, we recommend using the CRT-based S3 client. */ Map<String, String> userMetadata = new HashMap<>(); userMetadata.put("x-amz-meta-myKey", "myValue"); PutObjectRequest putObjectRequest = PutObjectRequest.builder() .bucket("amzn-s3-demo-bucket1") .key("k") .contentType("text/plain") //System-defined metadata usually has separate methods in the builder. .contentLength(22L) .metadata(userMetadata) //metadata() is only for user-defined metadata. .build(); UploadRequest uploadRequest = UploadRequest.builder() .putObjectRequest(putObjectRequest) .requestBody(AsyncRequestBody.fromInputStream(stream, 22L, executor)) .build(); transferManager.upload(uploadRequest).completionFuture().join();

uploadDirectory 使用 ObjectMetadataProvider 參數

  • uploadDirectory(String bucketName, String virtualDirectoryKeyPrefix, File directory, boolean includeSubdirectories, ObjectMetadataProvider metadataProvider)

  • uploadDirectory(String bucketName, String virtualDirectoryKeyPrefix, File directory, boolean includeSubdirectories, ObjectMetadataProvider metadataProvider, ObjectTaggingProvider taggingProvider)

  • uploadDirectory(String bucketName, String virtualDirectoryKeyPrefix, File directory, boolean includeSubdirectories, ObjectMetadataProvider metadataProvider, ObjectTaggingProvider taggingProvider, ObjectCannedAclProvider cannedAclProvider)

// V1 ---------------------------------------------------------------------------------------------- tm.uploadDirectory(bucketName, virtualDirectoryKeyPrefix, directory, includeSubdirectories, metadataProvider) tm.uploadDirectory(bucketName, virtualDirectoryKeyPrefix, directory, includeSubdirectories, metadataProvider, taggingProvider) tm.uploadDirectory(bucketName, virtualDirectoryKeyPrefix, directory, includeSubdirectories, metadataProvider, taggingProvider, cannedAclProvider) // V2 ---------------------------------------------------------------------------------------------- UploadDirectoryRequest request = UploadDirectoryRequest.builder() .bucket(bucketName) .s3Prefix(virtualDirectoryKeyPrefix) .source(directory.toPath()) .maxDepth(includeSubdirectories ? Integer.MAX_VALUE : 1) .uploadFileRequestTransformer(builder -> { // 1.Replace `ObjectMetadataProvider`, `ObjectTaggingProvider`, and `ObjectCannedAclProvider` with an // `UploadFileRequestTransformer` that can combine the functionality of all three *Provider implementations. // 2. Convert your v1 `ObjectMetadata` to v2 `PutObjectRequest` parameters. // 3. Convert your v1 `ObjectTagging` to v2 `Tagging`. // 4. Convert your v1 `CannedAccessControlList` to v2 `ObjectCannedACL`. }) .build(); DirectoryUpload directoryUpload = transferManager.uploadDirectory(request);

模型物件遷移

在 中 AWS SDK for Java 2.x,許多TransferManager模型物件已重新設計,不再支援 v1 模型物件中可用的多種 getter 和 setter 方法。

在 v2 中,您可以使用 CompletableFuture<T>類別在傳輸完成時執行動作,無論是成功還是例外。如有需要,您可以使用 join()方法等待完成。

核心傳輸物件

V1 類別 V2 類別 遷移狀態
TransferManager S3TransferManager ✅ 支援的
TransferManagerBuilder S3TransferManager.Builder ✅ 支援的
Transfer Transfer ✅ 支援的
AbortableTransfer Transfer ✅ 支援 (無個別類別)
Copy Copy ✅ 支援的
Download FileDownload ✅ 支援的
Upload Upload / FileUpload ✅ 支援的
MultipleFileDownload DirectoryDownload ✅ 支援的
MultipleFileUpload DirectoryUpload ✅ 支援的

持久性物件

V1 類別 V2 類別 遷移狀態
PersistableDownload ResumableFileDownload ✅ 支援的
PersistableUpload ResumableFileUpload ✅ 支援的
PersistableTransfer ResumableTransfer ✅ 支援的
PauseResult<T> 直接可繼續物件 ❌ 不支援

結果物件

V1 類別 V2 類別 遷移狀態
CopyResult CompletedCopy ✅ 支援的
UploadResult CompletedUpload ✅ 支援的

組態物件

V1 類別 V2 類別 遷移狀態
TransferManagerConfiguration MultipartConfiguration (在 Amazon S3 用戶端上) ✅ 支援的
TransferProgress TransferProgress + TransferProgressSnapshot ✅ 支援的
KeyFilter DownloadFilter ✅ 支援的

不支援的物件

V1 類別 V2 替代方案 遷移狀態
PauseStatus 不支援 ❌ 不支援
UploadContext 不支援 ❌ 不支援
ObjectCannedAclProvider PutObjectRequest.builder().acl() ❌ 不支援
ObjectMetadataProvider PutObjectRequest.builder().metadata() ❌ 不支援
ObjectTaggingProvider PutObjectRequest.builder().tagging() ❌ 不支援
PresignedUrlDownload 不支援 ❌ 不支援

TransferManagerBuilder 組態遷移

組態變更

您需要為 v2 Transfer Manager 設定的組態變更取決於您使用的 S3 用戶端。您可以選擇 AWS CRT 型 S3 用戶端或標準 Java 型 S3 非同步用戶端。如需差異的相關資訊,請參閱 中的 S3 用戶端 AWS SDK for Java 2.x主題。

Use the AWS CRT-based S3 client
設定 v1 v2 - 使用 AWS CRT 型 S3 用戶端的 Transfer Manager

(取得建置器)

TransferManagerBuilder tmBuilder = TransferManagerBuilder.standard();
S3TransferManager.Builder tmBuilder = S3TransferManager.builder();

S3 用戶端

tmBuilder.withS3Client(...); tmBuilder.setS3Client(...);
tmBuilder.s3Client(...);

執行器

tmBuilder.withExecutorFactory(...); tmBuilder.setExecutorFactory(...);
tmBuilder.executor(...);

關閉執行緒集區

tmBuilder.withShutDownThreadPools(...); tmBuilder.setShutdownThreadPools(...);
不支援。關閉 時,不會關閉提供的執行器 S3TransferManager

最小上傳部分大小

tmBuilder.withMinimumUploadPartSize(...); tmBuilder.setMinimumUploadPartSize(...);
S3AsyncClient s3 = S3AsyncClient.crtBuilder(). minimumPartSizeInBytes(...).build(); tmBuilder.s3Client(s3);

分段上傳閾值

tmBuilder.withMinimumUploadPartSize(...); tmBuilder.setMinimumUploadPartSize(...);
S3AsyncClient s3 = S3AsyncClient.crtBuilder(). thresholdInBytes(...).build(); tmBuilder.s3Client(s3);

最小複製部分大小

tmBuilder.withMinimumUploadPartSize(...); tmBuilder.setMinimumUploadPartSize(...);
S3AsyncClient s3 = S3AsyncClient.crtBuilder(). minimumPartSizeInBytes(...).build(); tmBuilder.s3Client(s3);

分段複製閾值

tmBuilder.withMinimumUploadPartSize(...); tmBuilder.setMinimumUploadPartSize(...);
S3AsyncClient s3 = S3AsyncClient.crtBuilder(). thresholdInBytes(...).build(); tmBuilder.s3Client(s3);

停用平行下載

tmBuilder.withDisableParallelDownloads(...); tmBuilder.setDisableParallelDownloads(...);
將停用分段 (預設) 的標準 Java 型 S3 用戶端傳遞至傳輸管理員,以停用平行下載。
S3AsyncClient s3 = S3AsyncClient.builder().build(); tmBuilder.s3Client(s3);

一律計算分段 md5

tmBuilder.withAlwaysCalculateMultipartMd5(...); tmBuilder.setAlwaysCalculateMultipartMd5(...);
不支援。
Use Java-based S3 async client
設定 v1 v2 - 使用 Java 型 S3 非同步用戶端的 Transfer Manager

(取得建置器)

TransferManagerBuilder tmBuilder = TransferManagerBuilder.standard();
S3TransferManager.Builder tmBuilder = S3TransferManager.builder();

S3 用戶端

tmBuilder.withS3Client(...); tmBuilder.setS3Client(...);
tmBuilder.s3Client(...);

執行器

tmBuilder.withExecutorFactory(...); tmBuilder.setExecutorFactory(...);
tmBuilder.executor(...);

關閉執行緒集區

tmBuilder.withShutDownThreadPools(...); tmBuilder.setShutdownThreadPools(...);
不支援。關閉 時,不會關閉提供的執行器 S3TransferManager

最小上傳部分大小

tmBuilder.withMinimumUploadPartSize(...); tmBuilder.setMinimumUploadPartSize(...);
S3AsyncClient s3 = S3AsyncClient.builder() .multipartConfiguration(cfg -> cfg.minimumPartSizeInBytes(...)).build(); tmBuilder.s3Client(s3);

分段上傳閾值

tmBuilder.withMinimumUploadPartSize(...); tmBuilder.setMinimumUploadPartSize(...);
S3AsyncClient s3 = S3AsyncClient.builder() .multipartConfiguration(cfg -> cfg.thresholdInBytes(...)).build(); tmBuilder.s3Client(s3);

最小複製部分大小

tmBuilder.withMinimumUploadPartSize(...); tmBuilder.setMinimumUploadPartSize(...);
S3AsyncClient s3 = S3AsyncClient.builder() .multipartConfiguration(cfg -> cfg.minimumPartSizeInBytes(...)).build(); tmBuilder.s3Client(s3);

分段複製閾值

tmBuilder.withMinimumUploadPartSize(...); tmBuilder.setMinimumUploadPartSize(...);
S3AsyncClient s3 = S3AsyncClient.builder() .multipartConfiguration(cfg -> cfg.thresholdInBytes(...)).build(); tmBuilder.s3Client(s3);

停用平行下載

tmBuilder.withDisableParallelDownloads(...); tmBuilder.setDisableParallelDownloads(...);
將停用分段 (預設) 的標準 Java 型 S3 用戶端傳遞至傳輸管理員,以停用平行下載。
S3AsyncClient s3 = S3AsyncClient.builder().build(); tmBuilder.s3Client(s3);

一律計算分段 md5

tmBuilder.withAlwaysCalculateMultipartMd5(...); tmBuilder.setAlwaysCalculateMultipartMd5(...);
不支援。

行為變更

非同步操作

V1 (封鎖):

Upload upload = transferManager.upload("amzn-s3-demo-bucket", "key", file); upload.waitForCompletion(); // Blocks until complete

V2 (非同步):

FileUpload upload = transferManager.uploadFile(UploadFileRequest.builder() .putObjectRequest(PutObjectRequest.builder() .bucket("amzn-s3-demo-bucket") .key("key") .build()) .source(file) .build()); CompletedFileUpload result = upload.completionFuture().join(); // Blocks until complete // Or handle asynchronously: upload.completionFuture().thenAccept(result -> { System.out.println("Upload completed: " + result.response().eTag()); });

錯誤處理

V1:如果任何子請求失敗,目錄傳輸會完全失敗。

V2:即使某些子請求失敗,目錄傳輸也會成功完成。明確檢查錯誤:

DirectoryUpload directoryUpload = transferManager.uploadDirectory(request); CompletedDirectoryUpload result = directoryUpload.completionFuture().join(); // Check for failed transfers if (!result.failedTransfers().isEmpty()) { System.out.println("Some uploads failed:"); result.failedTransfers().forEach(failed -> System.out.println("Failed: " + failed.exception().getMessage())); }

透過位元組範圍擷取平行下載

在 v2 SDK 中啟用自動平行傳輸功能時,S3 Transfer Manager 會使用位元組範圍擷取來平行擷取物件的特定部分 (分段下載)。使用 v2 下載物件的方式,不取決於最初上傳物件的方式。所有下載都可以受益於高輸送量和並行。

相反地,與 v1 的 Transfer Manager 相比,最初上傳物件的方式並不重要。v1 Transfer Manager 擷取物件組件的方式與上傳組件的方式相同。如果物件最初是以單一物件上傳,v1 Transfer Manager 就無法使用子請求加速下載程序。