Migrar o Gerenciador de Transferências da versão 1 para a versão 2 do AWS SDK para Java - AWS SDK for Java 2.x

Migrar o Gerenciador de Transferências da versão 1 para a versão 2 do AWS SDK para Java

Esse guia de migração aborda as principais diferenças entre o Gerenciador de Transferências v1 e o Gerenciador de Transferências v2 do S3, incluindo alterações no construtor, mapeamentos de métodos e exemplos de código para operações comuns. Depois de analisar essas diferenças, você pode migrar com êxito o código existente do Gerenciador de Transferências para aproveitar o desempenho aprimorado e as operações assíncronas na v2.

Sobre a ferramenta de migração do AWS SDK

O AWS SDK para Java fornece uma ferramenta de migração automatizada que pode migrar grande parte da API do Gerenciador de Transferências v1 para a v2. No entanto, a ferramenta de migração não é compatível com vários recursos do Gerenciador de Transferências v1. Nesses casos, você precisa migrar manualmente o código do Gerenciador de Transferências usando as orientações deste tópico.

Ao longo deste guia, o status da migração mostra se a ferramenta de migração pode migrar automaticamente um construtor, método ou recurso:

  • Compatível: a ferramenta de migração pode transformar automaticamente esse código

  • Incompatível: você precisa migrar o código manualmente

Mesmo para itens marcados com o status “Compatível”, revise os resultados da migração e faça um teste completo. A migração do Gerenciador de Transferências envolve mudanças de arquitetura significativas de operações síncronas para assíncronas.

Visão geral

O Gerenciador de Transferências do S3 v2 introduz mudanças significativas na API do Gerenciador de Transferências. O Gerenciador de Transferências do S3 v2 é baseado em operações assíncronas e oferece melhor desempenho, especialmente quando você usa o cliente Amazon S3 baseado no AWS CRT.

Principais diferenças

  • Pacote: com.amazonaws.services.s3.transfersoftware.amazon.awssdk.transfer.s3

  • Nome da classe: TransferManagerS3TransferManager

  • Dependência do cliente: cliente síncrono do Amazon S3 → cliente assíncrono do Amazon S3 (S3AsyncClient)

  • Arquitetura: operações síncronas → operações assíncronas com CompletableFuture

  • Desempenho: aprimorado com o suporte ao cliente baseado no AWS

Alterações de alto nível

Aspecto V1 V2
Dependência do Maven aws-java-sdk-s3 s3-transfer-manager
Pacote com.amazonaws.services.s3.transfer software.amazon.awssdk.transfer.s3
Classe principal TransferManager S3TransferManager
Cliente do Amazon S3 AmazonS3 (síncrono) S3AsyncClient (assíncrono)
Tipos de retorno Operações de bloqueio CompletableFuture<T>

Dependências do 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 Versão mais recente. 2 Versão mais recente. 3 Versão mais recente.

Migração do construtor do cliente

Construtores compatíveis (migração automática)

Construtor V1 V2 equivalente Status da migração
new TransferManager() S3TransferManager.create() Compatível
TransferManagerBuilder. defaultTransferManager() S3TransferManager.create() Compatível
TransferManagerBuilder. standard().build() S3TransferManager.builder().build() Compatível
new TransferManager(AWSCredentials) S3TransferManager.builder() .s3Client(S3AsyncClient.builder() .credentialsProvider(...).build()) .build() Compatível
new TransferManager( AWSCredentialsProvider) S3TransferManager.builder() .s3Client(S3AsyncClient.builder() .credentialsProvider(...).build()) .build() Compatível

Construtores incompatíveis (migração manual obrigatória)

Construtor V1 V2 equivalente Notas de migração
new TransferManager(AmazonS3) Migração manual obrigatória Criar um S3AsyncClient separadamente
new TransferManager(AmazonS3, ExecutorService) Migração manual obrigatória Criar um S3AsyncClient e configurar um executor
new TransferManager(AmazonS3, ExecutorService, boolean) Migração manual obrigatória Parâmetro shutDownThreadPools incompatível

Exemplos de migração manual

Código da V1:

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

Código da 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();

Migração do método do cliente

Atualmente, a ferramenta de migração é compatível com os métodos básicos copy, download, upload, uploadDirectory, downloadDirectory, resumeDownload e resumeUpload.

Métodos de transferência principais

Método da V1 Método da V2 Alteração do tipo de retorno Status da migração
upload(String, String, File) uploadFile(UploadFileRequest) UploadFileUpload Compatível
upload(PutObjectRequest) upload(UploadRequest) UploadUpload Compatível
download(String, String, File) downloadFile(DownloadFileRequest) DownloadFileDownload Compatível
download(GetObjectRequest, File) downloadFile(DownloadFileRequest) DownloadFileDownload Compatível
copy(String, String, String, String) copy(CopyRequest) CopyCopy Compatível
copy(CopyObjectRequest) copy(CopyRequest) CopyCopy Compatível
uploadDirectory(String, String, File, boolean) uploadDirectory( UploadDirectoryRequest) MultipleFileUploadDirectoryUpload Compatível
downloadDirectory(String, String, File) downloadDirectory( DownloadDirectoryRequest) MultipleFileDownloadDirectoryDownload Compatível

Métodos de transferência com retomada

Método da V1 Método da V2 Status da migração
resumeUpload(PersistableUpload) resumeUploadFile(ResumableFileUpload) Compatível
resumeDownload(PersistableDownload) resumeDownloadFile(ResumableFileDownload) Compatível

Métodos do ciclo de vida

Método da V1 Método da V2 Status da migração
shutdownNow() close() Compatível
shutdownNow(boolean) Ajustar manualmente o código usando o método close() Sem suporte

Métodos de cliente V1 incompatíveis

Método da V1 V2 alternativa Observações
abortMultipartUploads(String, Date) Use o cliente de nível baixo do Amazon S3 Sem suporte
getAmazonS3Client() Salvar uma referência separadamente Incompatível; não há getter na v2
getConfiguration() Salvar uma referência separadamente Incompatível; não há getter na v2
uploadFileList(...) Fazer várias chamadas uploadFile() Sem suporte
Métodos copy com um parâmetro TransferStateChangeListener Use TransferListener Consulte um exemplo de migração manual
Métodos download com um parâmetro S3ProgressListener Use TransferListener Consulte um exemplo de migração manual

Métodos downloadDirectory com quatro ou mais parâmetros

Consulte um exemplo de migração manual
Método upload com um parâmetro ObjectMetadataProvider Definir metadados na solicitação Consulte um exemplo de migração manual
Métodos uploadDirectory com um parâmetro *Provider Definir tags na solicitação Consulte um exemplo de migração manual

Métodos copy com um parâmetro 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);

Métodos download com um parâmetro 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.

Métodos downloadDirectory com quatro ou mais parâmetros

  • 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);

Método upload com um parâmetro 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 com parâmetro 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);

Migração de objetos de modelo

No AWS SDK for Java 2.x, muitos dos objetos do modelo TransferManager foram redefinidos e vários métodos getter e setter disponíveis nos objetos do modelo da v1 não são mais compatíveis.

Na v2, você pode usar a classe CompletableFuture<T> para realizar ações quando a transferência for concluída, seja com êxito ou com uma exceção. Você pode usar o método join() para aguardar a conclusão, se necessário.

Objetos de transferência principal

Classe V1 Classe V2 Status da migração
TransferManager S3TransferManager Compatível
TransferManagerBuilder S3TransferManager.Builder Compatível
Transfer Transfer Compatível
AbortableTransfer Transfer Compatível (sem classe separada)
Copy Copy Compatível
Download FileDownload Compatível
Upload Upload / FileUpload Compatível
MultipleFileDownload DirectoryDownload Compatível
MultipleFileUpload DirectoryUpload Compatível

Objetos de persistência

Classe V1 Classe V2 Status da migração
PersistableDownload ResumableFileDownload Compatível
PersistableUpload ResumableFileUpload Compatível
PersistableTransfer ResumableTransfer Compatível
PauseResult<T> Objeto com retomada direta Sem suporte

Objetos de resultado

Classe V1 Classe V2 Status da migração
CopyResult CompletedCopy Compatível
UploadResult CompletedUpload Compatível

Objetos de configuração

Classe V1 Classe V2 Status da migração
TransferManagerConfiguration MultipartConfiguration (no cliente do Amazon S3) Compatível
TransferProgress TransferProgress + TransferProgressSnapshot Compatível
KeyFilter DownloadFilter Compatível

Objetos não compatíveis

Classe V1 V2 alternativa Status da migração
PauseStatus Não compatível Sem suporte
UploadContext Não compatível Sem suporte
ObjectCannedAclProvider PutObjectRequest.builder().acl() Sem suporte
ObjectMetadataProvider PutObjectRequest.builder().metadata() Sem suporte
ObjectTaggingProvider PutObjectRequest.builder().tagging() Sem suporte
PresignedUrlDownload Não compatível Sem suporte

Migração de configuração de TransferManagerBuilder

Alterações de configuração

As alterações de configuração que você precisa definir para o Gerenciador de Transferências v2 dependem do cliente do S3 que você usa. Você pode escolher entre o cliente do S3 baseado no AWS CRT ou o cliente assíncrono do S3 padrão baseado em Java. Consulte informações sobre as diferenças no tópico Clientes do S3 no AWS SDK for Java 2.x.

Use the AWS CRT-based S3 client
Configuração v1 v2: Gerenciador de Transferências usando o cliente do S3 baseado no AWS CRT

(obtenha um construtor)

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

Cliente do S3

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

Executor

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

Encerrar grupos de threads

tmBuilder.withShutDownThreadPools(...); tmBuilder.setShutdownThreadPools(...);
Sem suporte. O executor fornecido não será desligado quando o S3TransferManager for fechado

Tamanho mínimo da parte de upload

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

Limite de multipart upload

tmBuilder.withMultipartUploadThreshold(...); tmBuilder.setMultipartUploadThreshold(...);
S3AsyncClient s3 = S3AsyncClient.crtBuilder(). thresholdInBytes(...).build(); tmBuilder.s3Client(s3);

Tamanho mínimo da parte de cópia

tmBuilder.withMultipartCopyPartSize(...); tmBuilder.setMultipartCopyPartSize(...);
S3AsyncClient s3 = S3AsyncClient.crtBuilder(). minimumPartSizeInBytes(...).build(); tmBuilder.s3Client(s3);

Limite de cópia de multipart

tmBuilder.withMultipartCopyThreshold(...); tmBuilder.setMultipartCopyThreshold(...);
S3AsyncClient s3 = S3AsyncClient.crtBuilder(). thresholdInBytes(...).build(); tmBuilder.s3Client(s3);

Desabilitar downloads paralelos

tmBuilder.withDisableParallelDownloads(...); tmBuilder.setDisableParallelDownloads(...);
Desabilite os downloads paralelos passando um cliente do S3 padrão baseado em Java com multipart desativado (padrão) para o Gerenciador de Transferências.
S3AsyncClient s3 = S3AsyncClient.builder().build(); tmBuilder.s3Client(s3);

Sempre calcule o multipart md5

tmBuilder.withAlwaysCalculateMultipartMd5(...); tmBuilder.setAlwaysCalculateMultipartMd5(...);
Sem compatibilidade.
Use Java-based S3 async client
Configuração v1 v2: Gerenciador de Transferências que usa o cliente assíncrono do S3 baseado em Java

(obtenha um construtor)

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

Cliente do S3

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

Executor

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

Encerrar grupos de threads

tmBuilder.withShutDownThreadPools(...); tmBuilder.setShutdownThreadPools(...);
Sem suporte. O executor fornecido não será desligado quando o S3TransferManager for fechado

Tamanho mínimo da parte de upload

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

Limite de multipart upload

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

Tamanho mínimo da parte de cópia

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

Limite de cópia de multipart

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

Desabilitar downloads paralelos

tmBuilder.withDisableParallelDownloads(...); tmBuilder.setDisableParallelDownloads(...);
Desabilite os downloads paralelos passando um cliente do S3 padrão baseado em Java com multipart desativado (padrão) para o Gerenciador de Transferências.
S3AsyncClient s3 = S3AsyncClient.builder().build(); tmBuilder.s3Client(s3);

Sempre calcule o multipart md5

tmBuilder.withAlwaysCalculateMultipartMd5(...); tmBuilder.setAlwaysCalculateMultipartMd5(...);
Sem compatibilidade.

Alteração de comportamento

Operações assíncronas

V1 (bloqueio):

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

V2 (assíncrono):

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

Tratamento de erros

V1: as transferências de diretórios falham completamente se alguma subsolicitação falha.

V2: as transferências de diretórios são concluídas com êxito mesmo se algumas subsolicitações falham. Verifique se há erros de forma explícita:

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

Download paralelo por meio de buscas de intervalo de bytes

Quando o recurso de transferência paralela automática está ativado no SDK v2, o Gerenciador de Transferências do S3 usa buscas de intervalo de bytes para recuperar partes específicas do objeto em paralelo (download multipart). A forma como um objeto é baixado com a v2 não depende de como o objeto foi originalmente carregado. Todos os downloads podem se beneficiar da alta taxa de transferência e da simultaneidade.

Por outro lado, com o Gerenciador de Transferências v1, faz diferença como o objeto foi originalmente carregado. O Gerenciador de Transferências v1 recupera as partes do objeto da mesma forma que as partes foram carregadas. Se um objeto foi originalmente carregado como um único objeto, o Gerenciador de transferência v1 não é capaz de acelerar o processo de download usando subsolicitações.