Condividi tramite


Trasferire dati con la libreria di Spostamento dati

Nota

Questo articolo include indicazioni per l'uso della versione 2.0.XX della libreria di spostamento dati Archiviazione di Azure. La versione 2.0.XX è attualmente in modalità di manutenzione e la libreria riceve solo correzioni per problemi di integrità e sicurezza dei dati. Non verranno aggiunte nuove funzionalità o funzionalità e le nuove versioni del servizio di archiviazione non saranno supportate dalla libreria.

Le versioni beta di una libreria di spostamento dati moderna sono attualmente in fase di sviluppo. Per altre informazioni, vedere Archiviazione di Azure libreria client comune di spostamento dati per .NET in GitHub.

La libreria di spostamento dati Archiviazione di Azure è una libreria open source multipiattaforma progettata per caricamento, download e copia di BLOB e file ad alte prestazioni. La libreria di spostamento dati fornisce metodi pratici che non sono disponibili nella libreria client Archiviazione di Azure per .NET. Questi metodi consentono di impostare il numero di operazioni parallele, tenere traccia dello stato di avanzamento del trasferimento, riprendere facilmente un trasferimento annullato e molto altro ancora.

La libreria usa inoltre .NET Core, utile quando si creano app .NET per Windows, Linux e macOS. Per altre informazioni su .NET Core, consultare la documentazione di .NET Core. La libreria è compatibile anche con le app .NET Framework tradizionali per Windows.

In questo documento viene spiegato come creare un'applicazione console di .NET Core da eseguire su Windows, Linux e macOS e vengono dimostrati gli scenari seguenti:

  • Caricare file e directory nell'archivio BLOB.
  • Definire il numero di operazioni parallele durante il trasferimento dati.
  • Monitorare lo stato del trasferimento dati.
  • Riprendere un trasferimento dati annullato.
  • Copiare file dall'URL all'archivio BLOB.
  • Copiare da archivio BLOB ad archivio BLOB.

Prerequisiti

Attrezzaggio

  1. Vedere la Guida all'installazione di .NET Core per installare .NET Core SDK. Quando si seleziona l'ambiente, scegliere l'opzione della riga di comando.
  2. Dalla riga di comando creare una directory per il progetto. Passare a questa directory, quindi digitare dotnet new console -o <sample-project-name> per creare un progetto console C#.
  3. Aprire la directory in Visual Studio Code. Questo passaggio può essere eseguito rapidamente tramite la riga di comando digitando code . in Windows.
  4. Installare l'estensione C# dal marketplace di Visual Studio Code. Riavviare Visual Studio Code.
  5. A questo punto compariranno due prompt. Uno consiste nell'aggiungere "asset necessari per la compilazione e il debug". Selezionare "sì". Un'altra richiesta consiste nel ripristinare le dipendenze non risolte. Selezionare "restore".
  6. Modificare launch.json in .vscode per usare il terminale esterno come una console. Questa impostazione deve essere impostata su "console": "externalTerminal"
  7. Visual Studio Code consente di eseguire il debug delle applicazioni di .NET Core. Premere F5 per eseguire l'applicazione e verificare che l'installazione funzioni. Verrà visualizzato il messaggio "Hello World!" stampato nella console.

Aggiungere la libreria di spostamento dati al progetto

  1. Aggiungere la versione più recente della libreria di spostamento dati alla dependencies sezione del <project-name>.csproj file. Al momento della redazione di questo documento, la versione è "Microsoft.Azure.Storage.DataMovement": "0.6.2"
  2. Per ripristinare il progetto dovrebbe essere visualizzato un prompt dei comandi. Selezionare il pulsante "ripristina". È inoltre possibile ripristinare il progetto dalla riga di comando digitando il comando dotnet restore nella radice della directory del progetto.

Modificare <project-name>.csproj:

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>netcoreapp2.0</TargetFramework>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="Microsoft.Azure.Storage.DataMovement" Version="0.6.2" />
        </ItemGroup>
    </Project>

Configurare il framework dell'applicazione

La prima cosa da fare è configurare il framework di codice per l'applicazione. Questo codice richiede un nome dell'account di archiviazione e una chiave dell'account e usa tali credenziali per creare un CloudStorageAccount oggetto. Questo oggetto viene usato per interagire con l'account di archiviazione in tutti gli scenari di trasferimento. Il codice consente inoltre di scegliere il tipo di operazione di trasferimento desiderata.

Modificare Program.cs:

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using Microsoft.Azure.Storage;
using Microsoft.Azure.Storage.Blob;
using Microsoft.Azure.Storage.DataMovement;

namespace DMLibSample
{
    public class Program
    {
        public static void Main()
        {
            Console.WriteLine("Enter Storage account name:");
            string accountName = Console.ReadLine();

            Console.WriteLine("\nEnter Storage account key:");
            string accountKey = Console.ReadLine();

            string storageConnectionString = "DefaultEndpointsProtocol=https;AccountName=" + accountName + ";AccountKey=" + accountKey;
            CloudStorageAccount account = CloudStorageAccount.Parse(storageConnectionString);

            ExecuteChoice(account);
        }

        public static void ExecuteChoice(CloudStorageAccount account)
        {
            Console.WriteLine("\nWhat type of transfer would you like to execute?\n1. Local file --> Azure Blob\n2. Local directory --> Azure Blob directory\n3. URL (e.g. Amazon S3 file) --> Azure Blob\n4. Azure Blob --> Azure Blob");
            int choice = int.Parse(Console.ReadLine());

            if(choice == 1)
            {
                TransferLocalFileToAzureBlob(account).Wait();
            }
            else if(choice == 2)
            {
                TransferLocalDirectoryToAzureBlobDirectory(account).Wait();
            }
            else if(choice == 3)
            {
                TransferUrlToAzureBlob(account).Wait();
            }
            else if(choice == 4)
            {
                TransferAzureBlobToAzureBlob(account).Wait();
            }
        }

        public static async Task TransferLocalFileToAzureBlob(CloudStorageAccount account)
        {

        }

        public static async Task TransferLocalDirectoryToAzureBlobDirectory(CloudStorageAccount account)
        {

        }

        public static async Task TransferUrlToAzureBlob(CloudStorageAccount account)
        {

        }

        public static async Task TransferAzureBlobToAzureBlob(CloudStorageAccount account)
        {

        }
    }
}

Importante

Questo esempio di codice usa una stringa di connessione per autorizzare l'accesso all'account di archiviazione. Questa configurazione è per scopi esemplificativi. Le stringhe di connessione e le chiavi di accesso dell'account devono essere usate con cautela nel codice dell'applicazione. Se la chiave di accesso dell'account va persa o viene accidentalmente inserita in una posizione non sicura, il servizio può diventare vulnerabile. Chiunque abbia la chiave di accesso può autorizzare richieste all'account di archiviazione e di fatto ha accesso a tutti i dati.

Caricare un file locale in un BLOB

Aggiungere i metodi GetSourcePath e GetBlob a Program.cs:

public static string GetSourcePath()
{
    Console.WriteLine("\nProvide path for source:");
    string sourcePath = Console.ReadLine();

    return sourcePath;
}

public static CloudBlockBlob GetBlob(CloudStorageAccount account)
{
    CloudBlobClient blobClient = account.CreateCloudBlobClient();

    Console.WriteLine("\nProvide name of Blob container:");
    string containerName = Console.ReadLine();
    CloudBlobContainer container = blobClient.GetContainerReference(containerName);
    container.CreateIfNotExistsAsync().Wait();

    Console.WriteLine("\nProvide name of new Blob:");
    string blobName = Console.ReadLine();
    CloudBlockBlob blob = container.GetBlockBlobReference(blobName);

    return blob;
}

Modificare il metodo TransferLocalFileToAzureBlob:

public static async Task TransferLocalFileToAzureBlob(CloudStorageAccount account)
{
    string localFilePath = GetSourcePath();
    CloudBlockBlob blob = GetBlob(account);
    Console.WriteLine("\nTransfer started...");
    await TransferManager.UploadAsync(localFilePath, blob);
    Console.WriteLine("\nTransfer operation complete.");
    ExecuteChoice(account);
}

Questo codice richiede il percorso di un file locale, il nome di un contenitore nuovo o esistente e il nome di un nuovo BLOB. Il metodo TransferManager.UploadAsync esegue il caricamento usando queste informazioni.

Premere F5 per eseguire l'applicazione. È possibile verificare l'avvenuto caricamento visualizzando l'account di archiviazione con Esplora archivi di Microsoft Azure.

Impostare il numero di operazioni parallele

La libreria di spostamento dati offre la possibilità di impostare il numero di operazioni parallele per aumentare la velocità effettiva del trasferimento dei dati. Per impostazione predefinita, la libreria di spostamento dati imposta il numero di operazioni parallele su 8 * il numero di core nel computer.

Tenere presente che molte operazioni parallele in un ambiente a larghezza di banda ridotta potrebbero sovraccaricare la connessione di rete e impedire effettivamente il completamento completo delle operazioni. È consigliabile provare questa impostazione per determinare il funzionamento migliore in base alla larghezza di banda di rete disponibile.

In questo esempio viene aggiunto codice che consente di impostare il numero di operazioni parallele. Si aggiunge anche il codice che indica il tempo necessario per il completamento del trasferimento.

Aggiungere un metodo SetNumberOfParallelOperations a Program.cs:

public static void SetNumberOfParallelOperations()
{
    Console.WriteLine("\nHow many parallel operations would you like to use?");
    string parallelOperations = Console.ReadLine();
    TransferManager.Configurations.ParallelOperations = int.Parse(parallelOperations);
}

Modificare il metodo ExecuteChoice in modo che usi SetNumberOfParallelOperations:

public static void ExecuteChoice(CloudStorageAccount account)
{
    Console.WriteLine("\nWhat type of transfer would you like to execute?\n1. Local file --> Azure Blob\n2. Local directory --> Azure Blob directory\n3. URL (e.g. Amazon S3 file) --> Azure Blob\n4. Azure Blob --> Azure Blob");
    int choice = int.Parse(Console.ReadLine());

    SetNumberOfParallelOperations();

    if(choice == 1)
    {
        TransferLocalFileToAzureBlob(account).Wait();
    }
    else if(choice == 2)
    {
        TransferLocalDirectoryToAzureBlobDirectory(account).Wait();
    }
    else if(choice == 3)
    {
        TransferUrlToAzureBlob(account).Wait();
    }
    else if(choice == 4)
    {
        TransferAzureBlobToAzureBlob(account).Wait();
    }
}

Modificare il metodo TransferLocalFileToAzureBlob in modo che usi un timer:

public static async Task TransferLocalFileToAzureBlob(CloudStorageAccount account)
{
    string localFilePath = GetSourcePath();
    CloudBlockBlob blob = GetBlob(account);
    Console.WriteLine("\nTransfer started...");
    Stopwatch stopWatch = Stopwatch.StartNew();
    await TransferManager.UploadAsync(localFilePath, blob);
    stopWatch.Stop();
    Console.WriteLine("\nTransfer operation completed in " + stopWatch.Elapsed.TotalSeconds + " seconds.");
    ExecuteChoice(account);
}

Monitorare lo stato del trasferimento dati

È possibile tenere traccia dello stato di avanzamento del trasferimento durante l'operazione di trasferimento creando un TransferContext oggetto . L'oggetto TransferContext è disponibile in due forme: SingleTransferContext per i trasferimenti di file singoli e DirectoryTransferContext per i trasferimenti di directory.

Aggiungere i metodi GetSingleTransferContext e GetDirectoryTransferContext a Program.cs:

public static SingleTransferContext GetSingleTransferContext(TransferCheckpoint checkpoint)
{
    SingleTransferContext context = new SingleTransferContext(checkpoint);

    context.ProgressHandler = new Progress<TransferStatus>((progress) =>
    {
        Console.Write("\rBytes transferred: {0}", progress.BytesTransferred );
    });

    return context;
}

public static DirectoryTransferContext GetDirectoryTransferContext(TransferCheckpoint checkpoint)
{
    DirectoryTransferContext context = new DirectoryTransferContext(checkpoint);

    context.ProgressHandler = new Progress<TransferStatus>((progress) =>
    {
        Console.Write("\rBytes transferred: {0}", progress.BytesTransferred );
    });

    return context;
}

Modificare il metodo TransferLocalFileToAzureBlob in modo che usi GetSingleTransferContext:

public static async Task TransferLocalFileToAzureBlob(CloudStorageAccount account)
{
    string localFilePath = GetSourcePath();
    CloudBlockBlob blob = GetBlob(account);
    TransferCheckpoint checkpoint = null;
    SingleTransferContext context = GetSingleTransferContext(checkpoint);
    Console.WriteLine("\nTransfer started...\n");
    Stopwatch stopWatch = Stopwatch.StartNew();
    await TransferManager.UploadAsync(localFilePath, blob, null, context);
    stopWatch.Stop();
    Console.WriteLine("\nTransfer operation completed in " + stopWatch.Elapsed.TotalSeconds + " seconds.");
    ExecuteChoice(account);
}

Riprendere un trasferimento annullato

Un'altra funzionalità offerta dalla libreria di spostamento dati è la possibilità di riprendere un trasferimento annullato. Successivamente, si aggiunge un codice che consente di annullare temporaneamente il trasferimento digitando ce quindi riprendere il trasferimento 3 secondi dopo.

Modificare il metodo TransferLocalFileToAzureBlob:

public static async Task TransferLocalFileToAzureBlob(CloudStorageAccount account)
{
    string localFilePath = GetSourcePath();
    CloudBlockBlob blob = GetBlob(account);
    TransferCheckpoint checkpoint = null;
    SingleTransferContext context = GetSingleTransferContext(checkpoint);
    CancellationTokenSource cancellationSource = new CancellationTokenSource();
    Console.WriteLine("\nTransfer started...\nPress 'c' to temporarily cancel your transfer...\n");

    Stopwatch stopWatch = Stopwatch.StartNew();
    Task task;
    ConsoleKeyInfo keyinfo;
    try
    {
        task = TransferManager.UploadAsync(localFilePath, blob, null, context, cancellationSource.Token);
        while(!task.IsCompleted)
        {
            if(Console.KeyAvailable)
            {
                keyinfo = Console.ReadKey(true);
                if(keyinfo.Key == ConsoleKey.C)
                {
                    cancellationSource.Cancel();
                }
            }
        }
        await task;
    }
    catch(Exception e)
    {
        Console.WriteLine("\nThe transfer is canceled: {0}", e.Message);
    }

    if(cancellationSource.IsCancellationRequested)
    {
        Console.WriteLine("\nTransfer will resume in 3 seconds...");
        Thread.Sleep(3000);
        checkpoint = context.LastCheckpoint;
        context = GetSingleTransferContext(checkpoint);
        Console.WriteLine("\nResuming transfer...\n");
        await TransferManager.UploadAsync(localFilePath, blob, null, context);
    }

    stopWatch.Stop();
    Console.WriteLine("\nTransfer operation completed in " + stopWatch.Elapsed.TotalSeconds + " seconds.");
    ExecuteChoice(account);
}

Fino ad ora, il checkpoint valore è stato impostato su null. A questo punto, se si annulla il trasferimento, viene recuperato l'ultimo checkpoint dell'operazione, che viene poi usato come nuovo checkpoint nel trasferimento.

Trasferire una directory locale nell'archiviazione BLOB

La libreria di spostamento dati consente di trasferire una directory di file e tutte le relative sottodirectory, come illustrato nell'esempio seguente.

Per prima cosa, aggiungere il metodo GetBlobDirectory a Program.cs:

public static CloudBlobDirectory GetBlobDirectory(CloudStorageAccount account)
{
    CloudBlobClient blobClient = account.CreateCloudBlobClient();

    Console.WriteLine("\nProvide name of Blob container. This can be a new or existing Blob container:");
    string containerName = Console.ReadLine();
    CloudBlobContainer container = blobClient.GetContainerReference(containerName);
    container.CreateIfNotExistsAsync().Wait();

    CloudBlobDirectory blobDirectory = container.GetDirectoryReference("");

    return blobDirectory;
}

Poi modificare TransferLocalDirectoryToAzureBlobDirectory:

public static async Task TransferLocalDirectoryToAzureBlobDirectory(CloudStorageAccount account)
{
    string localDirectoryPath = GetSourcePath();
    CloudBlobDirectory blobDirectory = GetBlobDirectory(account);
    TransferCheckpoint checkpoint = null;
    DirectoryTransferContext context = GetDirectoryTransferContext(checkpoint);
    CancellationTokenSource cancellationSource = new CancellationTokenSource();
    Console.WriteLine("\nTransfer started...\nPress 'c' to temporarily cancel your transfer...\n");

    Stopwatch stopWatch = Stopwatch.StartNew();
    Task task;
    ConsoleKeyInfo keyinfo;
    UploadDirectoryOptions options = new UploadDirectoryOptions()
    {
        Recursive = true
    };

    try
    {
        task = TransferManager.UploadDirectoryAsync(localDirectoryPath, blobDirectory, options, context, cancellationSource.Token);
        while(!task.IsCompleted)
        {
            if(Console.KeyAvailable)
            {
                keyinfo = Console.ReadKey(true);
                if(keyinfo.Key == ConsoleKey.C)
                {
                    cancellationSource.Cancel();
                }
            }
        }
        await task;
    }
    catch(Exception e)
    {
        Console.WriteLine("\nThe transfer is canceled: {0}", e.Message);
    }

    if(cancellationSource.IsCancellationRequested)
    {
        Console.WriteLine("\nTransfer will resume in 3 seconds...");
        Thread.Sleep(3000);
        checkpoint = context.LastCheckpoint;
        context = GetDirectoryTransferContext(checkpoint);
        Console.WriteLine("\nResuming transfer...\n");
        await TransferManager.UploadDirectoryAsync(localDirectoryPath, blobDirectory, options, context);
    }

    stopWatch.Stop();
    Console.WriteLine("\nTransfer operation completed in " + stopWatch.Elapsed.TotalSeconds + " seconds.");
    ExecuteChoice(account);
}

Esistono alcune differenze tra questo metodo e il metodo di caricamento di un singolo file. Attualmente sono in uso TransferManager.UploadDirectoryAsync e il metodo getDirectoryTransferContext creato in precedenza. Ora è disponibile anche un valore options per l'operazione di caricamento, che consente di indicare la volontà di includere le sottodirectory nel caricamento.

Copiare un file dall'URL a un BLOB

A questo punto, aggiungere un codice che consente di copiare un file da un URL a un BLOB di Azure.

Modificare TransferUrlToAzureBlob:

public static async Task TransferUrlToAzureBlob(CloudStorageAccount account)
{
    Uri uri = new Uri(GetSourcePath());
    CloudBlockBlob blob = GetBlob(account);
    TransferCheckpoint checkpoint = null;
    SingleTransferContext context = GetSingleTransferContext(checkpoint);
    CancellationTokenSource cancellationSource = new CancellationTokenSource();
    Console.WriteLine("\nTransfer started...\nPress 'c' to temporarily cancel your transfer...\n");

    Stopwatch stopWatch = Stopwatch.StartNew();
    Task task;
    ConsoleKeyInfo keyinfo;
    try
    {
        task = TransferManager.CopyAsync(uri, blob, CopyMethod.ServiceSideAsyncCopy, null, context, cancellationSource.Token);
        while(!task.IsCompleted)
        {
            if(Console.KeyAvailable)
            {
                keyinfo = Console.ReadKey(true);
                if(keyinfo.Key == ConsoleKey.C)
                {
                    cancellationSource.Cancel();
                }
            }
        }
        await task;
    }
    catch(Exception e)
    {
        Console.WriteLine("\nThe transfer is canceled: {0}", e.Message);
    }

    if(cancellationSource.IsCancellationRequested)
    {
        Console.WriteLine("\nTransfer will resume in 3 seconds...");
        Thread.Sleep(3000);
        checkpoint = context.LastCheckpoint;
        context = GetSingleTransferContext(checkpoint);
        Console.WriteLine("\nResuming transfer...\n");
        await TransferManager.CopyAsync(uri, blob, CopyMethod.ServiceSideAsyncCopy, null, context, cancellationSource.Token);
    }

    stopWatch.Stop();
    Console.WriteLine("\nTransfer operation completed in " + stopWatch.Elapsed.TotalSeconds + " seconds.");
    ExecuteChoice(account);
}

Un caso d'uso importante per questa funzionalità è quando è necessario spostare i dati da un altro servizio cloud ad Azure. Se si ha un URL che consente di accedere alla risorsa, è possibile spostare facilmente tale risorsa in BLOB di Azure usando il TransferManager.CopyAsync metodo . Questo metodo introduce anche un parametro CopyMethod . La tabella seguente illustra le opzioni disponibili per questo parametro:

Nome del membro valore Descrizione
SyncCopy 0 Scaricare i dati dall'origine alla memoria e caricare i dati dalla memoria alla destinazione. Attualmente disponibile solo per la copia da una risorsa Archiviazione di Azure a un'altra.
ServiceSideAsyncCopy 1 Inviare una richiesta di copia iniziale a Archiviazione di Azure per consentire la copia. Monitorare lo stato dell'operazione di copia fino al completamento della copia.
ServiceSideSyncCopy 2 Copiare il contenuto di ogni blocco con put block from URL, Append Block From URL o Put Page From URL (Inserisci pagina da URL).

Copiare un BLOC

Un'altra funzionalità fornita dalla libreria di spostamento dati è la possibilità di copiare da una risorsa Archiviazione di Azure a un'altra.

Modificare il metodo TransferAzureBlobToAzureBlob:

public static async Task TransferAzureBlobToAzureBlob(CloudStorageAccount account)
{
    CloudBlockBlob sourceBlob = GetBlob(account);
    CloudBlockBlob destinationBlob = GetBlob(account);
    TransferCheckpoint checkpoint = null;
    SingleTransferContext context = GetSingleTransferContext(checkpoint);
    CancellationTokenSource cancellationSource = new CancellationTokenSource();
    Console.WriteLine("\nTransfer started...\nPress 'c' to temporarily cancel your transfer...\n");

    Stopwatch stopWatch = Stopwatch.StartNew();
    Task task;
    ConsoleKeyInfo keyinfo;
    try
    {
        task = TransferManager.CopyAsync(sourceBlob, destinationBlob, CopyMethod.SyncCopy, null, context, cancellationSource.Token);
        while(!task.IsCompleted)
        {
            if(Console.KeyAvailable)
            {
                keyinfo = Console.ReadKey(true);
                if(keyinfo.Key == ConsoleKey.C)
                {
                    cancellationSource.Cancel();
                }
            }
        }
        await task;
    }
    catch(Exception e)
    {
        Console.WriteLine("\nThe transfer is canceled: {0}", e.Message);
    }

    if(cancellationSource.IsCancellationRequested)
    {
        Console.WriteLine("\nTransfer will resume in 3 seconds...");
        Thread.Sleep(3000);
        checkpoint = context.LastCheckpoint;
        context = GetSingleTransferContext(checkpoint);
        Console.WriteLine("\nResuming transfer...\n");
        await TransferManager.CopyAsync(sourceBlob, destinationBlob, CopyMethod.SyncCopy, null, context, cancellationSource.Token);
    }

    stopWatch.Stop();
    Console.WriteLine("\nTransfer operation completed in " + stopWatch.Elapsed.TotalSeconds + " seconds.");
    ExecuteChoice(account);
}

In questo esempio il parametro booleano in TransferManager.CopyAsync viene impostato su CopyMethod.SyncCopy per indicare che si desidera eseguire una copia sincrona. Questa configurazione significa che la risorsa viene scaricata prima nel computer locale, quindi caricata nel BLOB di Azure. L'opzione di copia sincrona è un ottimo modo per assicurarsi che l'operazione di copia avvenga a velocità costante. Al contrario, la velocità di una copia asincrona sul lato server dipende dalla larghezza di banda di rete disponibile sul server, che può variare. Tuttavia, la copia sincrona potrebbe generare costi in uscita aggiuntivi rispetto alla copia asincrona. L'approccio consigliato consiste nell'usare la copia sincrona in una macchina virtuale di Azure che si trova nella stessa area dell'account di archiviazione di origine per evitare costi in uscita.

L'applicazione di spostamento dati è stata completata. L'esempio di codice completo è disponibile su GitHub.

Passaggi successivi

Archiviazione di Azure documentazione di riferimento della libreria di spostamento dati.

Suggerimento

Gestire le risorse di archiviazione BLOB di Azure con Azure Storage Explorer. Azure Storage Explorer è un'app autonoma gratuita di Microsoft che consente di gestire risorse di Archiviazione BLOB di Azure. Azure Storage Explorer consente di creare in modo visivo, leggere, aggiornare ed eliminare contenitori BLOB e BLOB, nonché di gestirne l'accesso.