Transferir dados com a biblioteca de Movimentação de Dados
A biblioteca de Movimentação de Dados do Armazenamento do Azure é uma biblioteca de software livre multiplataforma para upload, download e cópia de alto desempenho de blobs e arquivos. A biblioteca de Movimentação de Dados contém métodos convenientes que não estão disponíveis na biblioteca de clientes do Armazenamento do Azure para .NET. Esses métodos permitem definir o número de operações paralelas, acompanhar o progresso da transferência, facilmente retomar uma transferência cancelada e muito mais.
A biblioteca de Movimentação de Dados só está disponível para .NET e só dá suporte ao Armazenamento de Blobs do Azure e aos Arquivos do Azure. Você deve considerar essas limitações e outros problemas conhecidos ao decidir se deseja usar a biblioteca de Movimentação de Dados.
Se você estiver migrando o código da biblioteca Microsoft.Azure.Storage.DataMovement mais antiga (versão 2.X.X) para a biblioteca Azure.Storage.DataMovement atual (versão 12.X.X), consulte o Guia de Migração.
Documentação da Referência de API | Código-fonte | Pacote (NuGet) | Exemplos: Blobs / Files.Shares
Pré-requisitos
- Assinatura do Azure - criar uma gratuitamente
- Conta de armazenamento do Azure – criar uma conta de armazenamento
- O último SDK do .NET para seu sistema operacional. Obtenha o SDK e não o runtime.
Configure seu ambiente
Se você não tiver um projeto existente, esta seção mostrará como configurar um projeto para funcionar com a biblioteca de clientes do Armazenamento de Blobs do Azure para .NET. As etapas incluem a instalação do pacote, a adição de diretivas using
e a criação de um objeto de cliente autorizado.
Instalar Pacotes
No diretório do projeto, instale pacotes para a biblioteca de clientes da Movimentação de Dados do Armazenamento do Azure e a biblioteca de clientes da Identidade do Azure usando o comando dotnet add package
. O pacote Azure.Identity é necessário para conexões sem senha com os serviços do Azure.
dotnet add package Azure.Storage.DataMovement
dotnet add package Azure.Storage.DataMovement.Blobs
dotnet add package Azure.Identity
Para trabalhar com a biblioteca de extensões para Arquivos do Azure, instale o pacote Azure.Storage.DataMovement.Files.Shares :
dotnet add package Azure.Storage.DataMovement.Files.Shares
Adicione diretivas using
Para executar os exemplos de código neste artigo, adicione as seguintes diretivas using
:
using Azure;
using Azure.Core;
using Azure.Identity;
using Azure.Storage.DataMovement;
using Azure.Storage.DataMovement.Blobs;
Se você estiver usando a biblioteca de extensões para Arquivos do Azure, adicione a seguinte diretiva using
:
using Azure.Storage.DataMovement.Files.Shares;
Autorização
O mecanismo de autorização deve ter as permissões necessárias para executar operações de upload, de download e de cópia. Para autorização com o Microsoft Entra ID (recomendado), você precisa da função interna de Colaborador de Dados de Blob de Armazenamento ou superior do RBAC do Azure.
Sobre a biblioteca de Movimentação de Dados
A biblioteca de Movimentação de Dados do Armazenamento do Azure consiste em uma biblioteca de clientes comum e em bibliotecas de extensão para o Armazenamento de Blobs do Azure e Arquivos do Azure. A biblioteca comum fornece a funcionalidade principal para transferir dados, enquanto as bibliotecas de extensão fornecem funcionalidades específicas ao Armazenamento de Blobs e aos Arquivos do Azure. Para saber mais, consulte os seguintes recursos:
Criar um objeto TransferManager
TransferManager é a classe principal para iniciar e controlar todos os tipos de transferências, incluindo upload, download e cópia. Nesta seção, você aprenderá a criar um objeto TransferManager
para trabalhar com um sistema de arquivos local, com o Armazenamento de Blobs ou com os Arquivos do Azure.
Observação
Uma prática recomendada para o gerenciamento de clientes do SDK do Azure é tratar um cliente como um singleton, o que significa que uma classe terá apenas um objeto de cada vez. Não há necessidade de manter mais de uma instância de um cliente para um determinado conjunto de parâmetros do construtor ou opções do cliente.
O código a seguir mostra como criar um objeto TransferManager
:
TransferManager transferManager = new(new TransferManagerOptions());
Opcionalmente, você pode fornecer uma instância de TransferManagerOptions ao construtor, que aplica determinadas opções de configuração a todas as transferências iniciadas pelo objeto TransferManager
. As seguintes opções de configuração estão disponíveis:
- CheckpointStoreOptions: opcional. Define as opções para criar um ponto de verificação usado para salvar o estado de transferência para que as transferências possam ser retomadas.
- Diagnostics: obtém as opções de diagnóstico do gerenciador de transferência.
-
ErrorHandling: opcional. Define como os erros são tratados durante uma transferência. O padrão é
StopOnAnyFailure
. - MaximumConcurrency: o número máximo de trabalhos que podem ser usados em uma transferência paralela.
- ProvidersForResuming: provedores de recursos para o gerenciador de transferência usar na retomada de uma transferência. Espera um provedor para cada provedor de armazenamento em uso. Para saber mais, confira Retomar uma transferência existente.
Criar um objeto StorageResource
StorageResource é a classe base para todos os recursos de armazenamento, incluindo blobs e arquivos. Para criar um objeto StorageResource
, use uma das seguintes classes de provedor:
-
BlobsStorageResourceProvider: use essa classe para criar instâncias
StorageResource
para um contêiner de blob, blob de blocos, blob de acréscimo ou blob de página. -
ShareFilesStorageResourceProvider: use essa classe para criar instâncias
StorageResource
para um arquivo ou diretório. -
LocalFilesStorageResourceProvider: use essa classe para criar instâncias
StorageResource
para um sistema de arquivos local.
Criar um objeto StorageResource
para o Armazenamento de Blobs
O código a seguir mostra como criar um objeto StorageResource
para contêineres de blob e blobs usando um Uri
:
// Create a token credential
TokenCredential tokenCredential = new DefaultAzureCredential();
BlobsStorageResourceProvider blobsProvider = new(tokenCredential);
// Get a container resource
StorageResource container = await blobsProvider.FromContainerAsync(
new Uri("http://<storage-account-name>.blob.core.windows.net/sample-container"));
// Get a block blob resource - default is block blob
StorageResource blockBlob = await blobsProvider.FromBlobAsync(
new Uri("http://<storage-account-name>.blob.core.windows.net/sample-container/sample-block-blob"),
new BlockBlobStorageResourceOptions());
// Use a similar approach to get a page blob or append blob resource
Você também pode criar um objeto StorageResource
usando um objeto cliente do Azure.Storage.Blobs.
// Create a token credential
TokenCredential tokenCredential = new DefaultAzureCredential();
BlobContainerClient blobContainerClient = new(
new Uri("https://<storage-account-name>.blob.core.windows.net/sample-container"),
tokenCredential);
StorageResource containerResource = BlobsStorageResourceProvider.FromClient(blobContainerClient);
BlockBlobClient blockBlobClient = blobContainerClient.GetBlockBlobClient("sample-block-blob");
StorageResource blockBlobResource = BlobsStorageResourceProvider.FromClient(blockBlobClient);
// Use a similar approach to get a page blob or append blob resource
Iniciar uma nova transferência
Todas as transferências precisam especificar uma origem e um destino. A origem e o destino são o tipo StorageResource
, que pode ser StorageResourceContainer
ou StorageResourceItem
. Para uma determinada transferência, a origem e o destino devem ser do mesmo tipo. Por exemplo, se a origem for um contêiner de blob, o destino deverá ser um contêiner de blob.
Você pode iniciar uma nova transferência chamando o seguinte método:
Esse método retorna um objeto TransferOperation que representa a transferência. Você pode usar o objeto TransferOperation
para monitorar o progresso da transferência ou obter a ID de transferência. A ID de transferência é um identificador exclusivo para a transferência que é necessária para retomar uma transferência ou pausar uma transferência.
Opcionalmente, você pode fornecer uma instância de TransferOptions para StartTransferAsync
ou ResumeTransferAsync
, que aplica determinadas opções de configuração a uma transferência específica. As seguintes opções de configuração estão disponíveis:
-
CreationMode: configura o comportamento quando uma transferência encontra um recurso que já existe. O padrão é
FailIfExists
ao iniciar uma nova transferência. Quando você retoma uma transferência, os padrões podem variar. Para todos os recursos enumerados com êxito quando a transferência foi iniciada,CreationMode
usa como padrão o valor inicial usado. Para todos os recursos restantes, o valor padrão regular se aplica. - InitialTransferSize: o tamanho da primeira solicitação de intervalo em bytes. Tamanhos de transferência simples menores que esse limite são carregados ou baixados em uma única solicitação. Transferências maiores que esse limite continuam sendo baixadas ou carregadas em partes de tamanho MaximumTransferChunkSize. O valor padrão é de 32 MiB. Quando você retoma uma transferência, o valor padrão é o valor especificado quando a transferência é iniciada pela primeira vez.
- MaximumTransferChunkSize: o tamanho máximo a ser usado para cada parte ao transferir dados em partes. O valor padrão é de 4 MiB. Quando você retoma uma transferência, o valor padrão é o valor especificado quando a transferência é iniciada pela primeira vez.
- ProgressHandlerOptions: opcional. Opções para alterar o comportamento do ProgressHandler.
Exemplo: carregar um diretório local em um contêiner de blob
O exemplo de código a seguir mostra como iniciar uma nova transferência para carregar um diretório local em um contêiner de blob:
// Create a token credential
TokenCredential tokenCredential = new DefaultAzureCredential();
TransferManager transferManager = new(new TransferManagerOptions());
BlobsStorageResourceProvider blobsProvider = new(tokenCredential);
string localDirectoryPath = "C:/path/to/directory";
Uri blobContainerUri = new Uri("https://<storage-account-name>.blob.core.windows.net/sample-container");
TransferOperation transferOperation = await transferManager.StartTransferAsync(
sourceResource: LocalFilesStorageResourceProvider.FromDirectory(localDirectoryPath),
destinationResource: await blobsProvider.FromContainerAsync(blobContainerUri));
await transferOperation.WaitForCompletionAsync();
Exemplo: copiar um contêiner ou blob
Você pode usar a biblioteca de Movimentação de Dados para copiar entre duas instâncias StorageResource
. Para recursos de blob, a transferência usa a operação Colocar Blob da URL, que executa uma cópia de servidor para servidor.
O exemplo de código a seguir mostra como iniciar uma nova transferência para copiar todos os blobs em um contêiner de blob de origem para um contêiner de blob de destino. O contêiner de destino já precisa existir. Neste exemplo, definimos CreationMode como OverwriteIfExists
para substituir todos os blobs de destino que já existem. Você pode ajustar a propriedade CreationMode
com base nas necessidades do seu aplicativo.
Uri sourceContainerUri = new Uri("https://<storage-account-name>.blob.core.windows.net/source-container");
Uri destinationContainerUri = new Uri("https://<storage-account-name>.blob.core.windows.net/dest-container");
TransferOperation transferOperation = await transferManager.StartTransferAsync(
sourceResource: await blobsProvider.FromContainerAsync(
sourceContainerUri,
new BlobStorageResourceContainerOptions()
{
BlobPrefix = "source/directory/prefix"
}),
destinationResource: await blobsProvider.FromContainerAsync(
destinationContainerUri,
new BlobStorageResourceContainerOptions()
{
// All source blobs are copied as a single type of destination blob
// Defaults to block blob, if not specified
BlobType = BlobType.Block,
BlobPrefix = "destination/directory/prefix"
}),
transferOptions: new TransferOptions()
{
CreationMode = StorageResourceCreationMode.OverwriteIfExists,
}
);
await transferOperation.WaitForCompletionAsync();
O exemplo de código a seguir mostra como iniciar uma nova transferência para copiar um blob de origem para um blob de destino. Neste exemplo, definimos CreationMode como OverwriteIfExists
para substituir o blob de destino se ele já existir. Você pode ajustar a propriedade CreationMode
com base nas necessidades do seu aplicativo.
Uri sourceBlobUri = new Uri(
"https://<storage-account-name>.blob.core.windows.net/source-container/source-blob");
Uri destinationBlobUri = new Uri(
"https://<storage-account-name>.blob.core.windows.net/dest-container/dest-blob");
TransferOperation transferOperation = await transferManager.StartTransferAsync(
sourceResource: await blobsProvider.FromBlobAsync(sourceBlobUri),
destinationResource: await blobsProvider.FromBlobAsync(destinationBlobUri, new BlockBlobStorageResourceOptions()),
transferOptions: new TransferOptions()
{
CreationMode = StorageResourceCreationMode.OverwriteIfExists,
}
);
await transferOperation.WaitForCompletionAsync();
Retomar uma transferência existente
Ao persistir o progresso da transferência para o disco, a biblioteca de Movimentação de Dados permite que você retome uma transferência que falhou antes da conclusão ou foi cancelada ou pausada. Para retomar uma transferência, o objeto TransferManager
deve ser configurado com instâncias StorageResourceProvider
capazes de remontar a transferência dos dados persistentes. Você pode usar a propriedade ProvidersForResuming
da classe TransferManagerOptions para especificar os provedores.
O exemplo de código a seguir mostra como inicializar um objeto TransferManager
capaz de retomar uma transferência entre o sistema de arquivos local e o Armazenamento de Blobs:
// Create a token credential
TokenCredential tokenCredential = new DefaultAzureCredential();
TransferManager transferManager = new(new TransferManagerOptions()
{
ProvidersForResuming = new List<StorageResourceProvider>()
{
new BlobsStorageResourceProvider(tokenCredential)
}
});
Para retomar uma transferência, chame o seguinte método:
Forneça a ID de transferência da transferência que você deseja retomar. A ID de transferência é um identificador exclusivo para a transferência retornada como parte do objeto TransferOperation
quando a transferência é iniciada. Se você não souber o valor da ID de transferência, poderá chamar TransferManager.GetTransfersAsync para localizar a transferência e sua ID correspondente.
O exemplo de código a seguir mostra como retomar uma transferência:
TransferOperation resumedTransfer = await transferManager.ResumeTransferAsync(transferId: ID);
Observação
O local dos dados de transferência persistentes será diferente do local padrão se TransferCheckpointStoreOptions for definido como parte de TransferManagerOptions
. Para retomar as transferências registradas com um repositório de ponto de verificação personalizado, você deve fornecer as mesmas opções de repositório de ponto de verificação para o objeto TransferManager
que retoma a transferência.
Monitorar o progresso da transferência
As transferências podem ser monitoradas e observadas por meio de vários mecanismos, dependendo das necessidades do seu aplicativo. Nesta seção, você aprenderá como monitorar o progresso da transferência usando o objeto TransferOperation
e como monitorar uma transferência usando eventos TransferOptions
.
Exemplo: monitorar o progresso da transferência usando o objeto TransferOperation
Você pode monitorar o progresso da transferência usando o objeto TransferOperation
retornado pelo método StartTransferAsync
. Você também pode chamar TransferManager.GetTransfersAsync para enumerar todas as transferências para um objeto TransferManager
.
O exemplo de código a seguir mostra como iterar em todas as transferências e gravar o estado de cada transferência em um arquivo de log:
async Task CheckTransfersAsync(TransferManager transferManager)
{
await foreach (TransferOperation transfer in transferManager.GetTransfersAsync())
{
using StreamWriter logStream = File.AppendText("path/to/log/file");
logStream.WriteLine(Enum.GetName(typeof(TransferState), transfer.Status.State));
}
}
TransferStatus define o status do trabalho de transferência.
TransferStatus
inclui as propriedades a seguir:
Propriedade | Type | Descrição |
---|---|---|
HasCompletedSuccessfully |
Booliano | Representa se a transferência for concluída com êxito sem nenhuma falha ou itens ignorados. |
HasFailedItems |
Booliano | Representa se a transferência tem itens de falha. Se definido como true , a transferência terá pelo menos um item de falha. Se definido como false , a transferência não tem falhas no momento. |
HasSkippedItems |
Booliano | Representa se a transferência tem itens ignorados. Se definido como true , a transferência terá pelo menos um item ignorado. Se definido como false , a transferência atualmente não tem itens ignorados. É possível nunca ter itens ignorados se SkipIfExists não estiver habilitado em TransferOptions.CreationMode. |
State |
TransferState | Define os tipos do estado que uma transferência pode ter. Consulte TransferState para obter detalhes. |
Exemplo: monitorar o progresso da transferência usando eventos TransferOptions
Você pode monitorar o progresso da transferência escutando eventos fornecidos pela classe TransferOptions. A instância TransferOptions
é passada para o método StartTransferAsync
e fornece eventos que são disparados quando uma transferência é concluída, falha, é ignorada ou altera o status.
O exemplo de código a seguir mostra como escutar um evento de conclusão de transferência usando TransferOptions
:
async Task<TransferOperation> ListenToTransfersAsync(
TransferManager transferManager,
StorageResource source,
StorageResource destination)
{
TransferOptions transferOptions = new();
transferOptions.ItemTransferCompleted += (TransferItemCompletedEventArgs args) =>
{
using (StreamWriter logStream = File.AppendText("path/to/log/file"))
{
logStream.WriteLine($"File Completed Transfer: {args.Source.Uri.AbsoluteUri}");
}
return Task.CompletedTask;
};
return await transferManager.StartTransferAsync(
source,
destination,
transferOptions);
}
Usar métodos de extensão para BlobContainerClient
Para aplicativos com código existente que usa a classe BlobContainerClient
de Azure.Storage.Blobs, você pode usar métodos de extensão para iniciar transferências diretamente de um objeto BlobContainerClient
. Os métodos de extensão são fornecidos na classe BlobContainerClientExtensions (ou ShareDirectoryClientExtensions para os Arquivos do Azure) e fornecem alguns dos benefícios de usar TransferManager
com alterações mínimas de código. Nesta seção, você aprenderá a usar os métodos de extensão para executar transferências de um objeto BlobContainerClient
.
Instale o pacote Azure.Storage.Blobs se você ainda não o tiver:
dotnet add package Azure.Storage.Blobs
Adicione as seguintes diretivas using
à parte superior do arquivo do seu código:
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
O exemplo de código a seguir mostra como criar uma instância do BlobContainerClient
para um contêiner de blob chamado sample-container
:
// Create a token credential
TokenCredential tokenCredential = new DefaultAzureCredential();
BlobServiceClient client = new BlobServiceClient(
new Uri("https://<storage-account-name>.blob.core.windows.net"),
tokenCredential);
BlobContainerClient containerClient = client.GetBlobContainerClient("sample-container");
O exemplo de código a seguir mostra como carregar o conteúdo do diretório local em sample-container
usando UploadDirectoryAsync
:
TransferOperation transfer = await containerClient
.UploadDirectoryAsync(WaitUntil.Started, "local/directory/path");
await transfer.WaitForCompletionAsync();
O exemplo de código a seguir mostra como baixar o conteúdo de sample-container
em um diretório local usando DownloadToDirectoryAsync
:
TransferOperation transfer = await containerClient
.DownloadToDirectoryAsync(WaitUntil.Started, "local/directory/path");
await transfer.WaitForCompletionAsync();
Para saber mais sobre os métodos de extensão, BlobContainerClient
consulte Extensões em BlobContainerClient.
Próxima etapa
- Códigos de exemplo para DataMovement.Blobs e DataMovement.Files.Shares estão disponíveis no SDK do Azure para o repositório GitHub do .NET.