Quickstart: Upload, download, and list blobs by using the Java Storage SDK V10

In this quickstart, you learn how to use the new Java Storage SDK to upload, download, and list block blobs in a container in Azure Blob storage. The new Java SDK uses the reactive programming model with RxJava, which provides asynchronous operations. Learn more about RxJava reactive extensions for the Java VM.

Prerequisites

To access Azure Storage, you'll need an Azure subscription. If you don't already have a subscription, then create a free account before you begin.

All access to Azure Storage takes place through a storage account. For this quickstart, create a storage account using the Azure portal, Azure PowerShell, or Azure CLI. For help creating the account, see Create a storage account.

Make sure you have the following additional prerequisites installed:

  • Maven to work from the command line, or any Java integrated development environment that you prefer.
  • JDK

Download the sample application

The sample application used in this quickstart is a basic console application.

Use git to download a copy of the application to your development environment.

git clone https://github.com/Azure-Samples/storage-blobs-java-v10-quickstart.git

This command clones the repository to your local git folder.

After the project finishes importing, open Quickstart.java, located in src/main/java/quickstart.

Copy your credentials from the Azure portal

The sample application needs to authorize access to your storage account. Provide your storage account credentials to the application in the form of a connection string. To view your storage account credentials:

  1. Navigate to the Azure portal.

  2. Locate your storage account.

  3. In the Settings section of the storage account overview, select Access keys. Your account access keys and connection string are displayed.

  4. Note the name of your storage account, which you'll need for authorization.

  5. Find the Key value under key1, and click the Copy button to copy the account key.

    Screenshot showing how to copy your account key from the Azure portal

Configure your storage connection string

This solution requires that you securely store the name and key of your storage account. Store them in environment variables local to the machine that runs the sample. Follow either the Linux or the Windows example, depending on your operating system, to create the environment variables.

Linux example

export AZURE_STORAGE_ACCOUNT="<youraccountname>"
export AZURE_STORAGE_ACCESS_KEY="<youraccountkey>"

Windows example

setx AZURE_STORAGE_ACCOUNT "<youraccountname>"
setx AZURE_STORAGE_ACCESS_KEY "<youraccountkey>"

Run the sample

This sample creates a test file in your default directory, AppData\Local\Temp, for Windows users. Then it prompts you to take the following steps:

  1. Enter commands to upload the test file to Azure Blob storage.
  2. List the blobs in the container.
  3. Download the uploaded file with a new name so you can compare the old and new files.

If you want to run the sample using Maven at the command line, open a shell and browse to storage-blobs-java-v10-quickstart inside your cloned directory. Then enter mvn compile exec:java.

This example shows your output if you run the application on Windows.

Created quickstart container
Enter a command
(P)utBlob | (L)istBlobs | (G)etBlob | (D)eleteBlobs | (E)xitSample
# Enter a command :
P
Uploading the sample file into the container: https://<storageaccount>.blob.core.windows.net/quickstart
# Enter a command :
L
Listing blobs in the container: https://<storageaccount>.blob.core.windows.net/quickstart
Blob name: SampleBlob.txt
# Enter a command :
G
Get the blob: https://<storageaccount>.blob.core.windows.net/quickstart/SampleBlob.txt
The blob was downloaded to C:\Users\<useraccount>\AppData\Local\Temp\downloadedFile13097087873115855761.txt
# Enter a command :
D
Delete the blob: https://<storageaccount>.blob.core.windows.net/quickstart/SampleBlob.txt

# Enter a command :
>> Blob deleted: https://<storageaccount>.blob.core.windows.net/quickstart/SampleBlob.txt
E
Cleaning up the sample and exiting!

You control the sample, so enter commands to have it run the code. Inputs are case sensitive.

You can also use a tool like the Azure Storage Explorer to view the files in Blob storage. Azure Storage Explorer is a free cross-platform tool that gives you access to your storage account information.

Verify the files. Then select E and select Enter to finish the demo and delete the test files. Now that you know what the sample does, open the Quickstart.java file to look at the code.

Understand the sample code

The following sections walk through the sample code so you can understand how it works.

Get references to the storage objects

First, you create the references to the objects that are used to access and manage Blob storage. These objects build on each other. Each is used by the next one in the list.

  1. Create an instance of the StorageURL object that points to the storage account.

    • The StorageURL object is a representation of your storage account. You use it to generate a new pipeline.
    • A pipeline is a set of policies that is used to manipulate requests and responses with authorization, logging, and retry mechanisms. For more information, see HTTP Pipeline.
    • By using the pipeline, create an instance of the ServiceURL object.
    • By using the ServiceURL object, create an instance of the ContainerURL.
    • The ContainerURL is necessary to run operations on blob containers.
  2. Create an instance of the ContainerURL object that represents the container you're accessing. Containers organize your blobs in the same way that folders on your computer organize your files.

    • The ContainerURL provides a point of access to the container service.
    • You can create an instance of the BlobURL object by using the ContainerURL.
    • The BlobURL is necessary to create blobs.
  3. Create an instance of the BlobURL object that points to the specific blob you're interested in.

Important

Container names must be lowercase. For more information about container and blob names, see Naming and Referencing Containers, Blobs, and Metadata.

Create a container

In this section, you create an instance of the ContainerURL. You create a new container along with it. The container in the sample is called quickstart.

This example uses ContainerURL.create, so you can create a new container each time the sample runs. Or you can create the container ahead of time, so you don't need to create it in the code.

// Create a ServiceURL to call the Blob service. We will also use this to construct the ContainerURL
SharedKeyCredentials creds = new SharedKeyCredentials(accountName, accountKey);
// We are using a default pipeline here, you can learn more about it at https://github.com/Azure/azure-storage-java/wiki/Azure-Storage-Java-V10-Overview
final ServiceURL serviceURL = new ServiceURL(new URL("http://" + accountName + ".blob.core.windows.net"), StorageURL.createPipeline(creds, new PipelineOptions()));

// Let's create a container using a blocking call to Azure Storage
// If container exists, we'll catch and continue
containerURL = serviceURL.createContainerURL("quickstart");

try {
    ContainersCreateResponse response = containerURL.create(null, null).blockingGet();
    System.out.println("Container Create Response was " + response.statusCode());
} catch (RestException e){
    if (e instanceof RestException && ((RestException)e).response().statusCode() != 409) {
        throw e;
    } else {
        System.out.println("quickstart container already exists, resuming...");
    }
}

Upload blobs to the container

Blob storage supports block blobs, append blobs, and page blobs. Block blobs are the most commonly used. They're used in this quickstart.

  1. To upload a file to a blob, get a reference to the blob in the target container.

  2. After you get the blob reference, you can upload a file to it by using either of the following APIs:

The sample code creates a local file to be used for the upload and download. It stores the file to be uploaded as sourceFile and stores the URL of the blob in blob. The following example uploads the file to your container called quickstart.

static void uploadFile(BlockBlobURL blob, File sourceFile) throws IOException {

    FileChannel fileChannel = FileChannel.open(sourceFile.toPath());

    // Uploading a file to the blobURL using the high-level methods available in TransferManager class
    // Alternatively call the Upload/StageBlock low-level methods from BlockBlobURL type
    TransferManager.uploadFileToBlockBlob(fileChannel, blob, 8*1024*1024, null)
        .subscribe(response-> {
            System.out.println("Completed upload request.");
            System.out.println(response.response().statusCode());
        });
}

Block blobs can be any type of text or binary file. Page blobs are primarily used for the VHD files used to back IaaS VMs. Append blobs are used to append data to the end, and they're often used for logging. Most objects stored in Blob storage are block blobs.

List the blobs in a container

You can get a list of objects in a container by using ContainerURL.listBlobsFlatSegment. This method returns up to 5,000 objects at once along with a continuation, or next, marker if there are more to list in the container. Create a helper function that calls itself repeatedly when there's a next marker in the previous listBlobsFlatSegment response.

static void listBlobs(ContainerURL containerURL) {
    // Each ContainerURL.listBlobsFlatSegment call return up to maxResults (maxResults=10 passed into ListBlobOptions below).
    // To list all Blobs, we are creating a helper static method called listAllBlobs,
    // and calling it after the initial listBlobsFlatSegment call
    ListBlobsOptions options = new ListBlobsOptions(null, null, 10);

    containerURL.listBlobsFlatSegment(null, options)
        .flatMap(containersListBlobFlatSegmentResponse ->
            listAllBlobs(containerURL, containersListBlobFlatSegmentResponse))
                .subscribe(response-> {
                    System.out.println("Completed list blobs request.");
                    System.out.println(response.statusCode());
                });
}

private static Single <ContainersListBlobFlatSegmentResponse> listAllBlobs(ContainerURL url, ContainersListBlobFlatSegmentResponse response) {
    // Process the blobs returned in this result segment (if the segment is empty, blobs() will be null.
    if (response.body().blobs() != null) {
        for (Blob b : response.body().blobs().blob()) {
            String output = "Blob name: " + b.name();
            if (b.snapshot() != null) {
                output += ", Snapshot: " + b.snapshot();
            }
            System.out.println(output);
        }
    }
    else {
        System.out.println("There are no more blobs to list off.");
    }

    // If there is not another segment, return this response as the final response.
    if (response.body().nextMarker() == null) {
        return Single.just(response);
    } else {
        /*
        IMPORTANT: ListBlobsFlatSegment returns the start of the next segment; you MUST use this to get the next
        segment (after processing the current result segment
        */

        String nextMarker = response.body().nextMarker();

        /*
        The presence of the marker indicates that there are more blobs to list, so we make another call to
        listBlobsFlatSegment and pass the result through this helper function.
        */

        return url.listBlobsFlatSegment(nextMarker, new ListBlobsOptions(null, null,1))
            .flatMap(containersListBlobFlatSegmentResponse ->
                listAllBlobs(url, containersListBlobFlatSegmentResponse));
    }
}

Download blobs

Download blobs to your local disk by using BlobURL.download.

The following code downloads the blob uploaded in a previous section. It adds a suffix of _DOWNLOADED to the blob name, so you can see both files on local disk.

static void getBlob(BlockBlobURL blobURL, File sourceFile) {
    try {
        // Get the blob using the low-level download method in BlockBlobURL type
        // com.microsoft.rest.v2.util.FlowableUtil is a static class that contains helpers to work with Flowable
        blobURL.download(new BlobRange(0, Long.MAX_VALUE), null, false)
            .flatMapCompletable(response -> {
                AsynchronousFileChannel channel = AsynchronousFileChannel.open(Paths
                    .get(sourceFile.getPath()), StandardOpenOption.CREATE,  StandardOpenOption.WRITE);
                        return FlowableUtil.writeFile(response.body(), channel);
            }).doOnComplete(()-> System.out.println("The blob was downloaded to " + sourceFile.getAbsolutePath()))
            // To call it synchronously add .blockingAwait()
            .subscribe();
    } catch (Exception ex){
        System.out.println(ex.toString());
    }
}

Clean up resources

If you don't need the blobs uploaded in this quickstart, you can delete the entire container by using ContainerURL.delete. This method also deletes the files in the container.

containerURL.delete(null).blockingGet();

Next steps

In this quickstart, you learned how to transfer files between a local disk and Azure Blob storage by using Java.