Caricare un BLOB con .NET

Questo articolo illustra come caricare un BLOB usando la libreria client di Archiviazione di Azure per .NET. È possibile caricare i dati in un BLOB a blocchi da un percorso di file, un flusso, un oggetto binario o una stringa di testo. È anche possibile aprire un flusso BLOB e scriverlo oppure caricare BLOB di grandi dimensioni in blocchi.

Prerequisiti

  • Questo articolo presuppone che sia già stato configurato un progetto per usare la libreria client Archiviazione BLOB di Azure per .NET. Per informazioni sulla configurazione del progetto, inclusa l'installazione del pacchetto, l'aggiunta using di direttive e la creazione di un oggetto client autorizzato, vedere Introduzione a Archiviazione BLOB di Azure e .NET.
  • Il meccanismo di autorizzazione deve disporre delle autorizzazioni per eseguire un'operazione di caricamento. Per altre informazioni, vedere le indicazioni sull'autorizzazione per le operazioni dell'API REST seguenti:

Caricare i dati in un BLOB a blocchi

È possibile usare uno dei metodi seguenti per caricare i dati in un BLOB a blocchi:

Quando si usano questi metodi di caricamento, la libreria client può chiamare Put BLOB o una serie di chiamate Put Block seguite da Put Block List. Questo comportamento dipende dalle dimensioni complessive dell'oggetto e dal modo in cui vengono impostate le opzioni di trasferimento dei dati .

Per aprire un flusso nell'archiviazione BLOB e scrivere in tale flusso, usare uno dei metodi seguenti:

Caricare un BLOB a blocchi da un percorso file locale

Nell'esempio seguente viene caricato un BLOB a blocchi da un percorso file locale:

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

    await blobClient.UploadAsync(localFilePath, true);
}

Caricare un BLOB a blocchi da un flusso

Nell'esempio seguente viene caricato un BLOB a blocchi creando un oggetto Stream e caricando il flusso.

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

Caricare un BLOB a blocchi da un oggetto BinaryData

Nell'esempio seguente viene caricato un BLOB a blocchi da un oggetto 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();
}

Caricare un BLOB a blocchi da una stringa

Nell'esempio seguente viene caricato un BLOB a blocchi da una stringa:

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

Caricare in un flusso nell'archiviazione BLOB

È possibile aprire un flusso in Archiviazione BLOB e scriverlo. Nell'esempio seguente viene creato un file zip in Archiviazione BLOB e si scrive i file. Invece di creare un file zip in memoria locale, solo un file alla volta è in memoria.

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

Caricare un BLOB a blocchi con opzioni di configurazione

È possibile definire le opzioni di configurazione della libreria client durante il caricamento di un BLOB. Queste opzioni possono essere ottimizzate per migliorare le prestazioni, migliorare l'affidabilità e ottimizzare i costi. Gli esempi di codice seguenti illustrano come usare BLOBUploadOptions per definire le opzioni di configurazione quando si chiama un metodo di caricamento.

Specificare le opzioni di trasferimento dei dati nel caricamento

È possibile configurare i valori in StorageTransferOptions per migliorare le prestazioni per le operazioni di trasferimento dei dati. Nell'esempio di codice seguente viene illustrato come impostare i valori per StorageTransferOptions e includere le opzioni come parte di un'istanza BlobUploadOptions . I valori forniti in questo esempio non sono destinati a essere una raccomandazione. Per ottimizzare correttamente questi valori, è necessario considerare le esigenze specifiche dell'app.

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

Per altre informazioni sulle opzioni di ottimizzazione del trasferimento dei dati, vedere Ottimizzazione delle prestazioni per i caricamenti e i download con .NET.

Specificare le opzioni di convalida del trasferimento nel caricamento

È possibile specificare le opzioni di convalida del trasferimento per assicurarsi che i dati vengano caricati correttamente e non siano stati manomessi durante il transito. Le opzioni di convalida di trasferimento possono essere definite a livello client usando BLOBClientOptions, che applica le opzioni di convalida a tutti i metodi chiamati da un'istanza BLOBClient .

È anche possibile eseguire l'override delle opzioni di convalida del trasferimento a livello di metodo usando BLOBUploadOptions. Nell'esempio di codice seguente viene illustrato come creare un oggetto e specificare un BlobUploadOptions algoritmo per la generazione di un checksum. Il checksum viene quindi usato dal servizio per verificare l'integrità dei dati del contenuto caricato.

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

La tabella seguente mostra le opzioni disponibili per l'algoritmo checksum, come definito da StorageChecksumAlgorithm:

Nome Valore Descrizione
Auto 0 Consigliato. Consente alla libreria di scegliere un algoritmo. Diverse versioni della libreria possono scegliere algoritmi diversi.
nessuno 1 Nessun algoritmo selezionato. Non calcolare o richiedere checksum.
MD5 2 Algoritmo hash MD5 standard.
StorageCrc64 3 Archiviazione di Azure personalizzata CRC a 64 bit.

Nota

Se il checksum specificato nella richiesta non corrisponde al checksum calcolato dal servizio, l'operazione di caricamento ha esito negativo. L'operazione non viene riprovata quando si usa un criterio di ripetizione dei tentativi predefinito. In .NET viene generato un RequestFailedException oggetto con codice di stato 400 e codice Md5Mismatch di errore o Crc64Mismatch, a seconda dell'algoritmo usato.

Caricare con tag di indice

I tag di indice BLOB categorizzano i dati nell'account di archiviazione usando attributi di tag chiave-valore. Questi tag vengono indicizzati automaticamente ed esposti come indice multidimensionale ricercabile per trovare facilmente i dati. È possibile aggiungere tag a un'istanza blobUploadOptions e passare tale istanza al UploadAsync metodo.

Nell'esempio seguente viene caricato un BLOB a blocchi con tag di indice:

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

Impostare il livello di accesso di un BLOB per il caricamento

È possibile impostare il livello di accesso di un BLOB su caricamento usando la classe BLOBUploadOptions . Nell'esempio di codice seguente viene illustrato come impostare il livello di accesso durante il caricamento di un 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();
}

L'impostazione del livello di accesso è consentita solo per i BLOB a blocchi. È possibile impostare il livello di accesso per un BLOB a blocchi su Hot, Cool, Coldo Archive. Per impostare il livello di accesso su Cold, è necessario usare una versione minima della libreria client 12.15.0.

Per altre informazioni sui livelli di accesso, vedere Panoramica dei livelli di accesso.

Caricare un BLOB a blocchi tramite blocchi di staging e eseguire il commit

È possibile avere un maggiore controllo su come dividere i caricamenti in blocchi eseguendo manualmente la gestione temporanea di singoli blocchi di dati. Quando vengono distribuiti tutti i blocchi che costituiscono un BLOB, è possibile eseguirne il commit nell'archiviazione BLOB. È possibile usare questo approccio per migliorare le prestazioni caricando blocchi in parallelo.

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

Risorse

Per altre informazioni sul caricamento di BLOB usando la libreria client di Archiviazione BLOB di Azure per .NET, vedere le risorse seguenti.

Operazioni dell'API REST

Azure SDK per .NET contiene librerie che si basano sull'API REST di Azure, consentendo di interagire con le operazioni dell'API REST tramite paradigmi .NET noti. I metodi della libreria client per il caricamento di BLOB usano le operazioni API REST seguenti:

Esempi di codice

Vedi anche