Uploads multipartes no Amazon S3 com Java

Uploads multipartes no Amazon S3 com Java

1. Visão geral

Neste tutorial, veremos como lidar com uploads de várias partes no Amazon S3 com AWS Java SDK.

Simply put, in a multipart upload, we split the content into smaller parts and upload each part individually. Todas as peças são remontadas quando recebidas.

Uploads multipartes oferecem as seguintes vantagens:

  • Maior rendimento - podemos fazer upload de peças em paralelo

  • Recuperação de erro mais fácil - precisamos recarregar apenas as partes com falha

  • Pausar e retomar os envios - podemos enviar peças a qualquer momento. Todo o processo pode ser pausado e as partes restantes podem ser carregadas posteriormente

Observe que ao usar o upload multipartwith Amazon S3, each part except the last part must be at least 5 MB in size.

2. Dependências do Maven

Antes de começarmos, precisamos adicionar a dependência do AWS SDK em nosso projeto:


    com.amazonaws
    aws-java-sdk
    1.11.290

Para ver a versão mais recente, verifiqueMaven Central.

3. Executando upload de várias partes

3.1. Criação do cliente Amazon S3

Primeiro, precisamoscreate a client for accessing Amazon S3.. UsaremosAmazonS3ClientBuilder para este propósito:

AmazonS3 amazonS3 = AmazonS3ClientBuilder
  .standard()
  .withCredentials(new DefaultAWSCredentialsProviderChain())
  .withRegion(Regions.DEFAULT_REGION)
  .build();

Isso cria um cliente usando a cadeia de fornecedores de credenciais padrão para acessar credenciais da AWS.

Para obter mais detalhes sobre como funciona a cadeia de provedor de credencial padrão, consultethe documentation. Se você estiver usando uma região diferente do padrão (US West-2), certifique-se de substituirRegions.DEFAULT_REGION por essa região personalizada.

3.2. Criação de TransferManager para gerenciamento de uploads

UsaremosTransferManagerBuilder para criar uma instânciaTransferManager.

Esta classeprovides simple APIs to manage uploads and downloads with Amazon S3e gerencia todas as tarefas relacionadas:

TransferManager tm = TransferManagerBuilder.standard()
  .withS3Client(amazonS3)
  .withMultipartUploadThreshold((long) (5 * 1024 * 1025))
  .build();

O limite de upload de várias partes especifica o tamanho, em bytes, acima do qual o upload deve ser executado como upload de várias partes.

O Amazon S3 impõe um tamanho mínimo de peça de 5 MB (para outras partes que não a última), portanto, usamos 5 MB como limite de upload de várias partes.

3.3. Carregando objeto

To upload object using TransferManager we simply need to call its upload() function. Isso carrega as peças em paralelo:

String bucketName = "example-bucket";
String keyName = "my-picture.jpg";
String file = new File("documents/my-picture.jpg");
Upload upload = tm.upload(bucketName, keyName, file);

TransferManager.upload() retorna um objetoUpload. Isso pode ser usado para verificar o status e gerenciar envios. Faremos isso na próxima seção.

3.4. Aguardando o upload ser concluído

TransferManager.upload() is a non-blocking function; ele retorna imediatamente enquanto o upload é executado em segundo plano.

Podemosuse the returned Upload object to wait for the upload to complete antes de sair do programa:

try {
    upload.waitForCompletion();
} catch (AmazonClientException e) {
    // ...
}

3.5. Acompanhando o andamento do upload

Acompanhar o andamento do upload é um requisito bastante comum; podemos fazer isso com a ajuda de uma instânciaProgressListener:

ProgressListener progressListener = progressEvent -> System.out.println(
  "Transferred bytes: " + progressEvent.getBytesTransferred());
PutObjectRequest request = new PutObjectRequest(
  bucketName, keyName, file);
request.setGeneralProgressListener(progressListener);
Upload upload = tm.upload(request);

OProgressListener que criamos simplesmente continuará a imprimir o número de bytes transferidos até que o upload seja concluído.

3.6. Controlando o paralelismo de upload

Por padrão,TransferManager usa no máximo dez threads para realizar uploads de várias partes.

Podemos, no entanto, controlar isso especificando umExecutorService ao construirTransferManager:

int maxUploadThreads = 5;
TransferManager tm = TransferManagerBuilder.standard()
  .withS3Client(amazonS3)
  .withMultipartUploadThreshold((long) (5 * 1024 * 1025))
  .withExecutorFactory(() -> Executors.newFixedThreadPool(maxUploadThreads))
  .build();

Aqui, usamos um lambda para criar uma implementação de wrapper deExecutorFactorye passamos para a funçãowithExecutorFactory().

4. Conclusão

Neste rápido artigo, aprendemos como realizar uploads com várias partes usando o AWS SDK para Java e vimos como controlar alguns aspectos do upload e acompanhar o seu progresso.

Como sempre, o código completo deste artigo está disponívelover on GitHub.