Upload a block blob with Java

This article shows how to upload a block blob using the Azure Storage client library for Java. You can upload data to a block blob from a file path, a stream, a binary object, or a text string. You can also upload blobs with index tags.

Prerequisites

  • This article assumes you already have a project set up to work with the Azure Blob Storage client library for Java. To learn about setting up your project, including package installation, adding import directives, and creating an authorized client object, see Get Started with Azure Storage and Java.
  • The authorization mechanism must have permissions to perform an upload operation. To learn more, see the authorization guidance for the following REST API operations:

Upload data to a block blob

To upload a block blob from a stream or a binary object, use the following method:

To upload a block blob from a file path, use the following method:

Each of these methods can be called using a BlobClient object or a BlockBlobClient object.

Upload a block blob from a local file path

The following example uploads a file to a block blob using a BlobClient object:

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

Upload a block blob from a stream

The following example uploads a block blob by creating a ByteArrayInputStream object, then uploading that stream object:

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

Upload a block blob from a BinaryData object

The following example uploads BinaryData to a block blob using a BlobClient object:

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

Upload a block blob with configuration options

You can define client library configuration options when uploading a blob. These options can be tuned to improve performance, enhance reliability, and optimize costs. The following code examples show how to use BlobUploadFromFileOptions to define configuration options when calling an upload method. If you're not uploading from a file, you can set similar options using BlobParallelUploadOptions on an upload method.

Specify data transfer options on upload

You can configure values in ParallelTransferOptions to improve performance for data transfer operations. The following values can be tuned for uploads based on the needs of your app:

  • blockSize: The maximum block size to transfer for each request. You can set this value by using the setBlockSizeLong method.
  • maxSingleUploadSize: If the size of the data is less than or equal to this value, it's uploaded in a single put rather than broken up into chunks. If the data is uploaded in a single shot, the block size is ignored. You can set this value by using the setMaxSingleUploadSizeLong method.
  • maxConcurrency: The maximum number of parallel requests issued at any given time as a part of a single parallel transfer. You can set this value by using the setMaxConcurrency method.

Make sure you have the following import directive to use ParallelTransferOptions for an upload:

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

The following code example shows how to set values for ParallelTransferOptions and include the options as part of a BlobUploadFromFileOptions instance. The values provided in this sample aren't intended to be a recommendation. To properly tune these values, you need to consider the specific needs of your 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());
    }
}

To learn more about tuning data transfer options, see Performance tuning for uploads and downloads with Java.

Upload a block blob with index tags

Blob index tags categorize data in your storage account using key-value tag attributes. These tags are automatically indexed and exposed as a searchable multi-dimensional index to easily find data.

The following example uploads a block blob with index tags set using 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());
    }
}

Set a blob's access tier on upload

You can set a blob's access tier on upload by using the BlobUploadFromFileOptions class. The following code example shows how to set the access tier when uploading a 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());
    }
}

Setting the access tier is only allowed for block blobs. You can set the access tier for a block blob to Hot, Cool, Cold, or Archive. To set the access tier to Cold, you must use a minimum client library version of 12.21.0.

To learn more about access tiers, see Access tiers overview.

Upload a block blob by staging blocks and committing

You can have greater control over how to divide uploads into blocks by manually staging individual blocks of data. When all of the blocks that make up a blob are staged, you can commit them to Blob Storage. You can use this approach to enhance performance by uploading blocks in parallel.

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

Resources

To learn more about uploading blobs using the Azure Blob Storage client library for Java, see the following resources.

REST API operations

The Azure SDK for Java contains libraries that build on top of the Azure REST API, allowing you to interact with REST API operations through familiar Java paradigms. The client library methods for uploading blobs use the following REST API operations:

Code samples

Client library resources

See also