Condividi tramite


Caricare un BLOB con .NET

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

Prerequisiti

Configurazione dell'ambiente

Se non si ha un progetto esistente, questa sezione spiega come configurare un progetto per l'uso con la libreria client di Archiviazione BLOB di Azure per .NET. I passaggi includono l'installazione del pacchetto, l'aggiunta di direttive using e la creazione di un oggetto client autorizzato. Per informazioni dettagliate, vedere Introduzione ad Archiviazione BLOB di Azure e .NET.

Installare i pacchetti

Nella directory del progetto installare i pacchetti per le librerie client di Archiviazione BLOB di Azure e Azure Identity usando il comando dotnet add package. Il pacchetto Azure.Identity è necessario per le connessioni senza password ai servizi di Azure.

dotnet add package Azure.Storage.Blobs
dotnet add package Azure.Identity

Aggiungere le direttive using

Aggiungere queste direttive using all'inizio del file del codice:

using Azure.Identity;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using Azure.Storage.Blobs.Specialized;

Alcuni esempi di codice in questo articolo potrebbero richiedere direttive using aggiuntive.

Creare un oggetto client

Per connettere un'app ad Archiviazione BLOB, creare un'istanza di BlobServiceClient. Nell'esempio seguente viene illustrato come creare un oggetto client usando DefaultAzureCredential per l'autorizzazione:

public BlobServiceClient GetBlobServiceClient(string accountName)
{
    BlobServiceClient client = new(
        new Uri($"https://{accountName}.blob.core.windows.net"),
        new DefaultAzureCredential());

    return client;
}

È possibile registrare un client del servizio per l'inserimento delle dipendenze in un'app .NET.

È anche possibile creare oggetti client per contenitori o BLOB specifici. Per altre informazioni sulla creazione e la gestione di oggetti client, vedere Creare e gestire oggetti client che interagiscono con le risorse dati.

Autorizzazione

Il meccanismo di autorizzazione deve disporre delle autorizzazioni necessarie per caricare un BLOB. Per l'autorizzazione con Microsoft Entra ID (scelta consigliata), è necessario disporre del ruolo predefinito di Controllo degli accessi in base al ruolo di Azure Collaboratore ai dati del BLOB di archiviazione o ruolo superiore. Per altre informazioni, vedere le indicazioni sulle autorizzazioni per Put Blob (API REST) e Put Block (API REST).

Caricare dati in un BLOB in blocchi

È possibile usare uno dei metodi seguenti per caricare i dati in un BLOB in 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 totali dell'oggetto e dal modo in cui sono 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 in blocchi da un percorso di file locale

L'esempio seguente carica un BLOB in blocchi da un percorso di 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 in blocchi da un flusso

L'esempio seguente carica un BLOB in 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 in blocchi da un oggetto BinaryData

Nell'esempio seguente viene caricato un BLOB in 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 in blocchi da una stringa

L'esempio seguente carica un BLOB in 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 nell'archivio BLOB e scrivervi. Nell'esempio seguente viene creato un file ZIP nell'archivio BLOB e vengono scritti i file. Invece di creare un file ZIP nella 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 in blocchi con le 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 e 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 durante il 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 di BlobUploadOptions. I valori forniti in questo esempio non sono necessariamente quelli consigliati. 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 sull'ottimizzazione delle opzioni di trasferimento dei dati, vedere Ottimizzazione delle prestazioni per i caricamenti e i download con .NET.

Specificare le opzioni di convalida del trasferimento al download

È possibile specificare le opzioni di convalida del trasferimento per assicurarsi che i dati vengano caricati correttamente e che non siano manomessi durante il transito. Le opzioni di convalida del trasferimento possono essere definite a livello di 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 BlobUploadOptions e specificare un 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 illustra le opzioni disponibili per l'algoritmo checksum, come definito da StorageChecksumAlgorithm:

Nome valore Descrizione
Automatico 0 Requisiti consigliati. Consente alla libreria di scegliere un algoritmo. Diverse versioni della libreria possono scegliere algoritmi diversi.
None 1 Nessun algoritmo selezionato. Non vengono calcolati o richiesti checksum.
MD5 2 Algoritmo hash MD5 standard.
StorageCrc64 3 CRC personalizzato di Archiviazione di Azure a 64 bit.

Nota

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

Caricare con tag indice

I tag indice BLOB categorizzano i dati nell'account di archiviazione usando gli attributi di tag chiave-valore. Questi tag vengono indicizzati e esposti automaticamente come indice multidimensionale ricercabile per facilitare la ricerca di dati. È possibile aggiungere tag a un'istanza BlobUploadOptions e passare tale istanza nel metodo UploadAsync.

L'esempio seguente carica un BLOB in blocchi con tag 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 durante il caricamento

È possibile impostare il livello di accesso di un BLOB durante il caricamento usando la classe BlobUploadOptions. L'esempio di codice seguente illustra 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 in blocchi. È possibile impostare il livello di accesso per un BLOB in blocchi su Hot, Cool, Cold o Archive. Per impostare il livello di accesso su Cold, è necessario usare una libreria client almeno alla versione 12.15.0.

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

Caricare un BLOB in blocchi tramite blocchi di staging e commit

È possibile avere un maggiore controllo su come dividere i caricamenti in blocchi eseguendo manualmente lo staging di singoli blocchi di dati. Quando tutti i blocchi che costituiscono un BLOB vengono gestiti in staging, è 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 con la libreria client di Archiviazione BLOB di Azure per .NET, vedere le risorse seguenti.

Esempi di codice

Operazioni dell'API REST

Azure SDK per .NET contiene librerie basate sull'API REST di Azure che consentono di interagire con le operazioni dell'API REST tramite paradigmi .NET noti. I metodi della libreria client per caricare i BLOB usano le operazioni API REST seguenti:

Vedi anche

  • Questo articolo fa parte della Guida per sviluppatori di Archiviazione BLOB per .NET. Per altre informazioni, vedere l’elenco completo degli articoli della Guida per sviluppatori inCreare la propria app .NET.