將 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();

用戶端方法遷移

目前,遷移工具支援基本 copydownload、、uploaduploadDirectorydownloadDirectoryresumeDownloadresumeUpload方法。

核心傳輸方法

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 就無法使用子請求加速下載程序。