Blob storage is for storing large amounts of semi-structured or unstructured data such as images, videos, documents etc. The blob service lets you create named containers that can then contain one or more named blobs which can be publicly (optional) accessed via an URI.

Creating blobs

void CreateTextBlobs() { auto storage_account = cloud_storage_account::parse( U("UseDevelopmentStorage=true")); auto blob_client = storage_account.create_cloud_blob_client(); auto container = blob_client.get_container_reference( U("textdata")); bool created = container.create_if_not_exists(); blob_container_permissions permissions; permissions.set_public_access( blob_container_public_access_type::container); container.upload_permissions(permissions); auto text_blob1 = container.get_block_blob_reference( U("texts/text1")); text_blob1.upload_text(U("This is some text - modified")); auto text_blob2 = container.get_block_blob_reference( U("texts/text2")); text_blob2.upload_from_file(U("./stdafx.h")); }

The classes/methods used are very similar to that used for table storage. Notice the use of blob_container_permissions to set the public access level for the container. It’s off by default, and you can optionally set it to blob (clients can read blob data) or container (clients can list blobs in the container and read blob data). You can simulate directories in the blob names. In the above example, both text1 and text2 are under the texts directory. This just affects the URI and are not physical directories.

Listing blobs

void ListTextBlobs() { auto storage_account = cloud_storage_account::parse( U("UseDevelopmentStorage=true")); auto blob_client = storage_account.create_cloud_blob_client(); auto container = blob_client.get_container_reference( U("textdata")); bool created = container.create_if_not_exists(); continuation_token token; auto result = container.list_blobs_segmented(token); for (auto dir : result.directories()) { ucout << U("Directory: ") << dir.uri().path() << endl; ucout << endl; continuation_token dir_token; auto resultInner = dir.list_blobs_segmented(dir_token); for (auto item : resultInner.blobs()) { ucout << item.name() << endl; ucout << item.uri().path() << endl; ucout << item.properties().content_type() << endl; ucout << endl; } } }

To list the blobs in a container, we need to use a continuation_token object. The container object supports a list_blobs_segmented method which takes this token. For each directory returned, we can then call list_blobs_segmented using a separate continuation_token object. Once we iterate through the blobs in the directory, we can access properties like the name, URI, content type etc. Here’s a sample output from calling the above fucntion.

Directory: /devstoreaccount1/textdata/texts/ texts/text1 /devstoreaccount1/textdata/texts/text1 text/plain; charset=utf-8 texts/text2 /devstoreaccount1/textdata/texts/text2 application/octet-stream

Notice how the text data we uploaded is of type text/plain whereas the file we uploaded is of type application/octet-stream. If you paste the first blob’s URI in a browser, the text is directly returned. Whereas in the second case, the file is offered for download – obviously this is browser specific behavior based on the content type.