Caricare un BLOB in blocchi con Java

Questo articolo illustra come caricare un BLOB in blocchi usando la libreria client di Archiviazione di Azure per Java. È 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 caricare BLOB con tag indice.

Prerequisiti

Configurazione dell'ambiente

Se non si ha un progetto esistente, questa sezione illustra come configurare un progetto per l’uso con la libreria client di Archiviazione BLOB di Azure per Java. Per altre informazioni, vedere Introduzione all’Archiviazione BLOB di Azure e Java.

Per usare gli esempi di codice in questo articolo, seguire questa procedura per configurare il progetto.

Nota

Questo articolo usa lo strumento di compilazione Maven per compilare ed eseguire il codice di esempio. Anche altri strumenti di compilazione, come Gradle, sono compatibili con Azure SDK per Java.

Installare i pacchetti

Aprire il file pom.xml nell'editor di testo. Installare i pacchetti includendo il file BOM o includendo una dipendenza diretta.

Aggiungere le istruzioni di importazione

Aggiungere le istruzioni import seguenti:

import com.azure.core.http.rest.*;
import com.azure.core.util.BinaryData;
import com.azure.storage.blob.*;
import com.azure.storage.blob.models.*;
import com.azure.storage.blob.options.BlobUploadFromFileOptions;
import com.azure.storage.blob.specialized.*;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.time.Duration;
import java.util.*;

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).

Creare un oggetto client

Per connettere un'app ad Archiviazione BLOB, creare un'istanza di BlobServiceClient.

L’esempio seguente usa BlobServiceClientBuilder per compilare un oggetto BlobServiceClient usando DefaultAzureCredential e illustra come creare client blob e contenitori, se necessario:

// Azure SDK client builders accept the credential as a parameter
// TODO: Replace <storage-account-name> with your actual storage account name
BlobServiceClient blobServiceClient = new BlobServiceClientBuilder()
        .endpoint("https://<storage-account-name>.blob.core.windows.net/")
        .credential(new DefaultAzureCredentialBuilder().build())
        .buildClient();

// If needed, you can create a BlobContainerClient object from the BlobServiceClient
BlobContainerClient containerClient = blobServiceClient
        .getBlobContainerClient("<container-name>");

// If needed, you can create a BlobClient object from the BlobContainerClient
BlobClient blobClient = containerClient
        .getBlobClient("<blob-name>");

Per altre informazioni sulla creazione e la gestione di oggetti client, vedere Creare e gestire oggetti client che interagiscono con le risorse dati.

Caricare dati in un BLOB in blocchi

Per caricare un BLOB in blocchi da un flusso o da un oggetto binario, usare il metodo seguente:

Per caricare un BLOB in blocchi da un percorso di file, usare il metodo seguente:

Ognuno di questi metodi può essere chiamato usando un oggetto BlobClient o un oggetto BlockBlobClient.

Caricare un BLOB in blocchi da un percorso di file locale

L'esempio seguente carica un file in un BLOB in blocchi usando un oggetto BlobClient:

public void uploadBlobFromFile(BlobContainerClient blobContainerClient) {
    BlobClient blobClient = blobContainerClient.getBlobClient("sampleBlob.txt");

    try {
        blobClient.uploadFromFile("filepath/local-file.png");
    } catch (UncheckedIOException ex) {
        System.err.printf("Failed to upload from file: %s%n", ex.getMessage());
    }
}

Caricare un BLOB in blocchi da un flusso

L'esempio seguente carica un BLOB in blocchi creando un oggetto ByteArrayInputStream e quindi caricando l'oggetto Stream:

public void uploadBlobFromStream(BlobContainerClient blobContainerClient) {
    BlockBlobClient blockBlobClient = blobContainerClient.getBlobClient("sampleBlob.txt").getBlockBlobClient();
    String sampleData = "Sample data for blob";
    try (ByteArrayInputStream dataStream = new ByteArrayInputStream(sampleData.getBytes())) {
        blockBlobClient.upload(dataStream, sampleData.length());
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

Caricare un BLOB in blocchi da un oggetto BinaryData

L'esempio seguente carica un BinaryData in un BLOB in blocchi usando un oggetto BlobClient:

public void uploadDataToBlob(BlobContainerClient blobContainerClient) {
    // Create a BlobClient object from BlobContainerClient
    BlobClient blobClient = blobContainerClient.getBlobClient("sampleBlob.txt");
    String sampleData = "Sample data for blob";
    blobClient.upload(BinaryData.fromString(sampleData));
}

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 BlobUploadFromFileOptions per definire le opzioni di configurazione quando si chiama un metodo di caricamento. Se non si esegue il caricamento da un file, è possibile impostare opzioni simili usando BlobParallelUploadOptions in un metodo di caricamento.

Specificare le opzioni di trasferimento dei dati durante il caricamento

È possibile configurare valori in ParallelTransferOptions per migliorare le prestazioni delle operazioni di trasferimento dei dati. È possibile ottimizzare i valori seguenti relativi ai caricamenti in base alle esigenze dell'app:

  • blockSize: dimensioni massime del blocco da trasferire per ogni richiesta. È possibile impostare questo valore usando il metodo setBlockSizeLong.
  • maxSingleUploadSize: se le dimensioni dei dati sono minori o uguali a questo valore, i dati vengono caricati in un'unica partizione anziché suddivisi in blocchi. Se i dati vengono caricati in una volta sola, la dimensione del blocco viene ignorata. È possibile impostare questo valore usando il metodo setMaxSingleUploadSizeLong.
  • maxConcurrency: numero massimo di richieste parallele generate in qualsiasi momento come parte di un singolo trasferimento parallelo. È possibile impostare questo valore usando il metodo setMaxConcurrency.

Assicurarsi di disporre della direttiva import seguente per usare ParallelTransferOptions per un caricamento:

import com.azure.storage.blob.models.*;

Nell'esempio di codice seguente viene illustrato come impostare i valori per ParallelTransferOptions e includere le opzioni come parte di un'istanza di BlobUploadFromFileOptions. I valori forniti in questo esempio non sono necessariamente quelli consigliati. Per ottimizzare correttamente questi valori è necessario considerare le esigenze specifiche dell'app.

public void uploadBlockBlobWithTransferOptions(BlobContainerClient blobContainerClient, Path filePath) {
    String fileName = filePath.getFileName().toString();
    BlobClient blobClient = blobContainerClient.getBlobClient(fileName);

    ParallelTransferOptions parallelTransferOptions = new ParallelTransferOptions()
            .setBlockSizeLong((long) (4 * 1024 * 1024)) // 4 MiB block size
            .setMaxConcurrency(2)
            .setMaxSingleUploadSizeLong((long) 8 * 1024 * 1024); // 8 MiB max size for single request upload

    BlobUploadFromFileOptions options = new BlobUploadFromFileOptions(filePath.toString());
    options.setParallelTransferOptions(parallelTransferOptions);

    try {
        Response<BlockBlobItem> blockBlob = blobClient.uploadFromFileWithResponse(options, null, null);
    } catch (UncheckedIOException ex) {
        System.err.printf("Failed to upload from file: %s%n", ex.getMessage());
    }
}

Per altre informazioni sull'ottimizzazione delle opzioni di trasferimento dei dati, vedere Ottimizzazione delle prestazioni per i caricamenti e i download con Java.

Caricare un BLOB in blocchi 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.

L'esempio seguente carica un BLOB in blocchi con tag di indice impostati usando BlobUploadFromFileOptions:

public void uploadBlockBlobWithIndexTags(BlobContainerClient blobContainerClient, Path filePath) {
    String fileName = filePath.getFileName().toString();
    BlobClient blobClient = blobContainerClient.getBlobClient(fileName);

    Map<String, String> tags = new HashMap<String, String>();
    tags.put("Content", "image");
    tags.put("Date", "2022-01-01");

    Duration timeout = Duration.ofSeconds(10);

    BlobUploadFromFileOptions options = new BlobUploadFromFileOptions(filePath.toString());
    options.setTags(tags);

    try {
        // Create a new block blob, or update the content of an existing blob
        Response<BlockBlobItem> blockBlob = blobClient.uploadFromFileWithResponse(options, timeout, null);
    } catch (UncheckedIOException ex) {
        System.err.printf("Failed to upload from file: %s%n", ex.getMessage());
    }
}

Impostare il livello di accesso di un BLOB durante il caricamento

È possibile impostare il livello di accesso di un BLOB al caricamento usando la classe BlobUploadFromFileOptions. L'esempio di codice seguente illustra come impostare il livello di accesso durante il caricamento di un BLOB:

public void uploadBlobWithAccessTier(BlobContainerClient blobContainerClient, Path filePath) {
    String fileName = filePath.getFileName().toString();
    BlobClient blobClient = blobContainerClient.getBlobClient(fileName);

    BlobUploadFromFileOptions options = new BlobUploadFromFileOptions(filePath.toString())
            .setTier(AccessTier.COOL);

    try {
        Response<BlockBlobItem> blockBlob = blobClient.uploadFromFileWithResponse(options, null, null);
    } catch (UncheckedIOException ex) {
        System.err.printf("Failed to upload from file: %s%n", ex.getMessage());
    }
}

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, Coldo Archive. Per impostare il livello di accesso su Cold, è necessario usare una libreria client almeno alla versione 12.21.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 void uploadBlocks(BlobContainerClient blobContainerClient, Path filePath, int blockSize) throws IOException {
    String fileName = filePath.getFileName().toString();
    BlockBlobClient blobClient = blobContainerClient.getBlobClient(fileName).getBlockBlobClient();

    FileInputStream fileStream = new FileInputStream(filePath.toString());
    List<String> blockIDArrayList = new ArrayList<>();
    byte[] buffer = new byte[blockSize];
    int bytesRead;

    while ((bytesRead = fileStream.read(buffer, 0, blockSize)) != -1) {

        try (ByteArrayInputStream stream = new ByteArrayInputStream(buffer)) {
            String blockID = Base64.getEncoder().encodeToString(UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8));

            blockIDArrayList.add(blockID);
            blobClient.stageBlock(blockID, stream, buffer.length);
        }
    }

    blobClient.commitBlockList(blockIDArrayList);

    fileStream.close();
}

Risorse

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

Esempi di codice

Operazioni dell'API REST

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

Risorse della libreria client

Vedi anche

  • Questo articolo fa parte della guida per sviluppatori di Archiviazione BLOB per Java. Per altre informazioni, vedere l'elenco completo degli articoli della Guida per sviluppatori in Creare la propria app Java.