Tue, 14 Jun 2011

Appending to a Windows Azure Block Blob

The question of how to append to a block blob came up on the Windows Azure forums, and I ended up writing a small console program to illustrate how it’s done. I thought I’d share the code here too:

static void Main(string[] args)
{
    if (args.Length < 3)
    {
        Console.WriteLine("Usage:");
        Console.WriteLine("AppendBlob <storage-connection-string> <path-to-blob> <text-to-append>");
        Console.WriteLine(@"(e.g. AppendBlob
            DefaultEndpointsProtocol=http;AccountName=myaccount;AccountKey=v1vf48...
            test/test.txt ""Hello, World!"")");
        Console.WriteLine(@"NOTE: AppendBlob doesn't work with development storage. Use a real
            cloud storage account.");
        Environment.Exit(1);
    }
    var blob = CloudStorageAccount.Parse(args[0]).CreateCloudBlobClient().GetBlockBlobReference(args[1]);
    List<string> blockIds = new List<string>();
    try
    {
        Console.WriteLine("Former contents:");
        Console.WriteLine(blob.DownloadText());
        blockIds.AddRange(blob.DownloadBlockList(BlockListingFilter.Committed).Select(b => b.Name));
    }
    catch (StorageClientException e)
    {
        if (e.ErrorCode != StorageErrorCode.BlobNotFound)
        {
            throw;
        }
        Console.WriteLine("Blob does not yet exist. Creating...");
        blob.Container.CreateIfNotExist();
    }
    var newId = Convert.ToBase64String(Encoding.Default.GetBytes(blockIds.Count.ToString()));
    blob.PutBlock(newId, new MemoryStream(Encoding.Default.GetBytes(args[2])), null);
    blockIds.Add(newId);
    blob.PutBlockList(blockIds);

    Console.WriteLine("New contents:");
    Console.WriteLine(blob.DownloadText());
}

As the usage text says, this doesn’t seem to work against development storage, so use the real thing.

Very similar code can be used to insert, delete, replace, and reorder blocks. For more information, see the MSDN documentation for Put Block and Put Block List.