Carregar um blob com .NET

Este artigo mostra como carregar um blob com a biblioteca de cliente do Armazenamento do Microsoft Azure para .NET. Pode carregar dados para um blob de blocos a partir de um caminho de ficheiro, de um fluxo, de um objeto binário ou de uma cadeia de texto. Também pode abrir um fluxo de blobs e escrever no mesmo ou carregar blobs grandes em blocos.

Pré-requisitos

  • Este artigo pressupõe que já tem um projeto configurado para funcionar com a biblioteca de cliente Armazenamento de Blobs do Azure para .NET. Para saber mais sobre como configurar o projeto, incluindo a instalação de pacotes, a adição using de diretivas e a criação de um objeto de cliente autorizado, veja Introdução ao Armazenamento de Blobs do Azure e .NET.
  • O mecanismo de autorização tem de ter permissões para executar uma operação de carregamento. Para saber mais, veja a documentação de orientação de autorização para as seguintes operações da API REST:

Carregar dados para um blob de blocos

Pode utilizar qualquer um dos seguintes métodos para carregar dados para um blob de blocos:

Ao utilizar estes métodos de carregamento, a biblioteca de cliente pode chamar Put Blob ou uma série de chamadas Put Block seguidas por Put Block List. Este comportamento depende do tamanho geral do objeto e da forma como as opções de transferência de dados são definidas.

Para abrir um fluxo no Armazenamento de Blobs e escrever nesse fluxo, utilize um dos seguintes métodos:

Carregar um blob de blocos a partir de um caminho de ficheiro local

O exemplo seguinte carrega um blob de blocos a partir de um caminho de ficheiro local:

public static async Task UploadFromFileAsync(
    BlobContainerClient containerClient,
    string localFilePath)
{
    string fileName = Path.GetFileName(localFilePath);
    BlobClient blobClient = containerClient.GetBlobClient(fileName);

    await blobClient.UploadAsync(localFilePath, true);
}

Carregar um blob de blocos a partir de um fluxo

O exemplo seguinte carrega um blob de blocos ao criar um objeto do Stream e ao carregar o fluxo.

public static async Task UploadFromStreamAsync(
    BlobContainerClient containerClient,
    string localFilePath)
{
    string fileName = Path.GetFileName(localFilePath);
    BlobClient blobClient = containerClient.GetBlobClient(fileName);

    FileStream fileStream = File.OpenRead(localFilePath);
    await blobClient.UploadAsync(fileStream, true);
    fileStream.Close();
}

Carregar um blob de blocos a partir de um objeto BinaryData

O exemplo seguinte carrega um blob de blocos a partir de um objeto BinaryData .

public static async Task UploadFromBinaryDataAsync(
    BlobContainerClient containerClient,
    string localFilePath)
{
    string fileName = Path.GetFileName(localFilePath);
    BlobClient blobClient = containerClient.GetBlobClient(fileName);

    FileStream fileStream = File.OpenRead(localFilePath);
    BinaryReader reader = new BinaryReader(fileStream);

    byte[] buffer = new byte[fileStream.Length];
    reader.Read(buffer, 0, buffer.Length);
    BinaryData binaryData = new BinaryData(buffer);

    await blobClient.UploadAsync(binaryData, true);

    fileStream.Close();
}

Carregar um blob de blocos a partir de uma cadeia

O exemplo seguinte carrega um blob de blocos a partir de uma cadeia:

public static async Task UploadFromStringAsync(
    BlobContainerClient containerClient,
    string blobName)
{
    BlobClient blobClient = containerClient.GetBlobClient(blobName);
    string blobContents = "Sample blob data";

    await blobClient.UploadAsync(BinaryData.FromString(blobContents), overwrite: true);
}

Carregar para um fluxo no Armazenamento de Blobs

Pode abrir um fluxo no Armazenamento de Blobs e escrever no mesmo. O exemplo seguinte cria um ficheiro zip no Armazenamento de Blobs e escreve ficheiros no mesmo. Em vez de criar um ficheiro zip na memória local, apenas um ficheiro de cada vez está na memória.

public static async Task UploadToStreamAsync(
    BlobContainerClient containerClient,
    string localDirectoryPath)
{
    string zipFileName = Path.GetFileName(
        Path.GetDirectoryName(localDirectoryPath)) + ".zip";

    BlockBlobClient blockBlobClient = containerClient.GetBlockBlobClient(zipFileName);

    using (Stream stream = await blockBlobClient.OpenWriteAsync(true))
    {
        using (ZipArchive zip = new ZipArchive(stream, ZipArchiveMode.Create, leaveOpen: false))
        {
            foreach (var fileName in Directory.EnumerateFiles(localDirectoryPath))
            {
                using (var fileStream = File.OpenRead(fileName))
                {
                    var entry = zip.CreateEntry(
                        Path.GetFileName(fileName), CompressionLevel.Optimal);
                    using (var innerFile = entry.Open())
                    {
                        await fileStream.CopyToAsync(innerFile);
                    }
                }
            }
        }
    }
}

Carregar um blob de blocos com opções de configuração

Pode definir opções de configuração da biblioteca de cliente ao carregar um blob. Estas opções podem ser otimizadas para melhorar o desempenho, melhorar a fiabilidade e otimizar os custos. Os exemplos de código seguintes mostram como utilizar BlobUploadOptions para definir opções de configuração ao chamar um método de carregamento.

Especificar opções de transferência de dados no carregamento

Pode configurar os valores em StorageTransferOptions para melhorar o desempenho das operações de transferência de dados. O exemplo de código seguinte mostra como definir valores para StorageTransferOptions e incluir as opções como parte de uma BlobUploadOptions instância. Os valores fornecidos neste exemplo não se destinam a ser uma recomendação. Para otimizar corretamente estes valores, tem de considerar as necessidades específicas da sua aplicação.

public static async Task UploadWithTransferOptionsAsync(
    BlobContainerClient containerClient,
    string localFilePath)
{
    string fileName = Path.GetFileName(localFilePath);
    BlobClient blobClient = containerClient.GetBlobClient(fileName);

    var transferOptions = new StorageTransferOptions
    {
        // Set the maximum number of parallel transfer workers
        MaximumConcurrency = 2,

        // Set the initial transfer length to 8 MiB
        InitialTransferSize = 8 * 1024 * 1024,

        // Set the maximum length of a transfer to 4 MiB
        MaximumTransferSize = 4 * 1024 * 1024
    };

    var uploadOptions = new BlobUploadOptions()
    {
        TransferOptions = transferOptions
    };

    FileStream fileStream = File.OpenRead(localFilePath);
    await blobClient.UploadAsync(fileStream, uploadOptions);
    fileStream.Close();
}

Para saber mais sobre como otimizar as opções de transferência de dados, veja Otimização do desempenho para carregamentos e transferências com o .NET.

Especificar opções de validação de transferência no carregamento

Pode especificar opções de validação de transferência para ajudar a garantir que os dados são carregados corretamente e não foram adulterados durante o trânsito. As opções de validação de transferência podem ser definidas ao nível do cliente com BlobClientOptions, que aplica opções de validação a todos os métodos chamados a partir de uma instância blobClient .

Também pode substituir as opções de validação de transferência ao nível do método com BlobUploadOptions. O exemplo de código seguinte mostra como criar um BlobUploadOptions objeto e especificar um algoritmo para gerar uma soma de verificação. Em seguida, a soma de verificação é utilizada pelo serviço para verificar a integridade dos dados do conteúdo carregado.

public static async Task UploadWithChecksumAsync(
    BlobContainerClient containerClient,
    string localFilePath)
{
    string fileName = Path.GetFileName(localFilePath);
    BlobClient blobClient = containerClient.GetBlobClient(fileName);

    var validationOptions = new UploadTransferValidationOptions
    {
        ChecksumAlgorithm = StorageChecksumAlgorithm.Auto
    };

    var uploadOptions = new BlobUploadOptions()
    {
        TransferValidation = validationOptions
    };

    FileStream fileStream = File.OpenRead(localFilePath);
    await blobClient.UploadAsync(fileStream, uploadOptions);
    fileStream.Close();
}

A tabela seguinte mostra as opções disponíveis para o algoritmo de soma de verificação, conforme definido por StorageChecksumAlgorithm:

Name Valor Descrição
Automático 0 Recomendado. Permite que a biblioteca escolha um algoritmo. Diferentes versões da biblioteca podem escolher algoritmos diferentes.
Nenhuma 1 Nenhum algoritmo selecionado. Não calcule nem solicite somas de verificação.
MD5 2 Algoritmo hash MD5 padrão.
StorageCrc64 3 CRC personalizado de 64 bits do Armazenamento do Microsoft Azure.

Nota

Se a soma de verificação especificada no pedido não corresponder à soma de verificação calculada pelo serviço, a operação de carregamento falhará. A operação não é repetida ao utilizar uma política de repetição predefinida. No .NET, é gerado um RequestFailedException com o código de estado 400 e o código Md5Mismatch de erro ou Crc64Mismatch, consoante o algoritmo utilizado.

Carregar com etiquetas de índice

As etiquetas de índice de blobs categorizam os dados na sua conta de armazenamento com atributos de etiqueta de chave-valor. Estas etiquetas são indexadas e expostas automaticamente como um índice multidimensional pesquisável para localizar facilmente dados. Pode adicionar etiquetas a uma instância blobUploadOptions e transmitir essa instância para o UploadAsync método .

O exemplo seguinte carrega um blob de blocos com etiquetas de índice:

public static async Task UploadBlobWithTagsAsync(
    BlobContainerClient containerClient,
    string blobName)
{
    BlobClient blobClient = containerClient.GetBlobClient(blobName);
    string blobContents = "Sample blob data";

    BlobUploadOptions options = new BlobUploadOptions();
    options.Tags = new Dictionary<string, string>
    {
        { "Sealed", "false" },
        { "Content", "image" },
        { "Date", "2020-04-20" }
    };

    await blobClient.UploadAsync(BinaryData.FromString(blobContents), options);
}

Definir a camada de acesso de um blob no carregamento

Pode definir a camada de acesso de um blob no carregamento com a classe BlobUploadOptions . O exemplo de código seguinte mostra como definir a camada de acesso ao carregar um blob:

public static async Task UploadWithAccessTierAsync(
    BlobContainerClient containerClient,
    string localFilePath)
{
    string fileName = Path.GetFileName(localFilePath);
    BlockBlobClient blockBlobClient = containerClient.GetBlockBlobClient(fileName);

    var uploadOptions = new BlobUploadOptions()
    {
        AccessTier = AccessTier.Cool
    };

    FileStream fileStream = File.OpenRead(localFilePath);
    await blockBlobClient.UploadAsync(fileStream, uploadOptions);
    fileStream.Close();
}

A definição da camada de acesso só é permitida para blobs de blocos. Pode definir a camada de acesso de um blob de blocos como Hot, Cool, Coldou Archive. Para definir a camada de acesso como Cold, tem de utilizar uma versão mínima da biblioteca de cliente 12.15.0.

Para saber mais sobre as camadas de acesso, veja Access tiers overview (Descrição geral das camadas de acesso).

Carregar um blob de blocos através de blocos de teste e consolidação

Pode ter um maior controlo sobre como dividir carregamentos em blocos ao testar manualmente blocos individuais de dados. Quando todos os blocos que compõem um blob são testados, pode consolidá-los no Armazenamento de Blobs. Pode utilizar esta abordagem para melhorar o desempenho ao carregar blocos em paralelo.

public static async Task UploadBlocksAsync(
    BlobContainerClient blobContainerClient,
    string localFilePath,
    int blockSize)
{
    string fileName = Path.GetFileName(localFilePath);
    BlockBlobClient blobClient = blobContainerClient.GetBlockBlobClient(fileName);

    FileStream fileStream = File.OpenRead(localFilePath);
    ArrayList blockIDArrayList = new ArrayList();
    byte[] buffer;

    var bytesLeft = (fileStream.Length - fileStream.Position);

    while (bytesLeft > 0)
    {
        if (bytesLeft >= blockSize)
        {
            buffer = new byte[blockSize];
            await fileStream.ReadAsync(buffer, 0, blockSize);
        }
        else
        {
            buffer = new byte[bytesLeft];
            await fileStream.ReadAsync(buffer, 0, Convert.ToInt32(bytesLeft));
            bytesLeft = (fileStream.Length - fileStream.Position);
        }

        using (var stream = new MemoryStream(buffer))
        {
            string blockID = Convert.ToBase64String(
                Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()));

            blockIDArrayList.Add(blockID);
            await blobClient.StageBlockAsync(blockID, stream);
        }
        bytesLeft = (fileStream.Length - fileStream.Position);
    }

    string[] blockIDArray = (string[])blockIDArrayList.ToArray(typeof(string));

    await blobClient.CommitBlockListAsync(blockIDArray);
}

Recursos

Para saber mais sobre como carregar blobs com a biblioteca de cliente Armazenamento de Blobs do Azure para .NET, veja os seguintes recursos.

Operações da API REST

O SDK do Azure para .NET contém bibliotecas que se baseiam na API REST do Azure, o que lhe permite interagir com operações da API REST através de paradigmas de .NET familiares. Os métodos da biblioteca de cliente para carregar blobs utilizam as seguintes operações da API REST:

Exemplos de código

Ver também