官术网_书友最值得收藏!

Uploading blocks to a block blob

The Windows Azure Blob Service supports two types of blobs: block blobs optimized for streaming, and page blobs optimized for random access. Block blobs are so named because they comprise blocks and can be updated by either replacing the entire blob or by replacing individual blocks. Page blobs can be updated by either replacing the entire blob or by modifying individual pages.

A block blob can be up to 200 GB, and comprises blocks that can be up to 4 MB. Block blobs larger than 64 MB must be uploaded in blocks and then a list of uploaded blocks must be committed to create the blob. The various upload methods in the CloudBlob class handle this two-phase process automatically. However, there are times when it is worthwhile taking direct control of the block upload and commit process. These include: uploading very large blobs, performing parallel uploads of blocks, or updating individual blocks.

At any given time, a block blob can comprise a set of committed blocks and a set of uncommitted blocks. Only the committed blocks are visible when the blob is accessed. The block blob can be updated by committing some mixture of the committed and uncommitted blocks. Any uncommitted blocks are garbage collected seven days after the last time blocks were committed to the block blob.

In this recipe, we will learn how to upload individual blocks and commit them to a block blob.

How to do it...

We are going to upload some blocks and commit them as a block blob. Then we are going to upload some more blocks to the same blob and retrieve the block list to confirm that the blob comprises a mixture of committed blocks and uncommitted blocks. Finally, we are going to commit the latest blocks and confirm that all the blocks in the blob have been committed. We do this as follows:

  1. Add a new class named UploadBlockBlobsExample to the project.
  2. Set the Target Framework for the project to.NET Framework 4.
  3. Add the following assembly references to the project:
    Microsoft.WindowsAzure.StorageClient
    System.Configuration
  4. Add the following using statements to the top of the class file:
    using Microsoft.WindowsAzure;
    using Microsoft.WindowsAzure.StorageClient;
    using System.Configuration;
  5. Add the following member to the class:
    private CloudBlockBlob cloudBlockBlob;
  6. Add the following constructor to the class:
    public UploadBlockBlobsExample(String containerName,String blobName)
    {
      CloudStorageAccount cloudStorageAccount =CloudStorageAccount.Parse(ConfigurationManager.AppSettings["DataConnectionString"]);
      CloudBlobClient cloudBlobClient =cloudStorageAccount.CreateCloudBlobClient();
    
      CloudBlobContainer cloudBlobContainer =cloudBlobClient.GetContainerReference(containerName);
      cloudBlobContainer.CreateIfNotExist();
      cloudBlockBlob =cloudBlobContainer.GetBlockBlobReference(blobName);
    }
  7. Add the following methods, uploading blobs, to the class:
    private IEnumerable<String> UploadBlocks(Int32 numberOfBlocks)
    {
      String[] base64EncodedBlockIds =new String[numberOfBlocks];
      for (Int32 blockId = 0; blockId < numberOfBlocks;blockId++)
      {
        base64EncodedBlockIds[blockId] =PutBlockFromStream(blockId);
      }
    
      return base64EncodedBlockIds;
    }
    private String PutBlockFromStream(Int32 blockId)
    {
      String base64EncodedBlockId = Convert.ToBase64String(System.BitConverter.GetBytes(blockId));
      String blobText = new String('z', 1000);
      UTF8Encoding utf8Encoding = new UTF8Encoding();
      using (MemoryStream memoryStream = newMemoryStream(utf8Encoding.GetBytes(blobText)))
      {
        cloudBlockBlob.PutBlock(base64EncodedBlockId,memoryStream, null);
      }
      return base64EncodedBlockId;
    }
  8. Add the following methods, handling block lists, to the class:
    private void PutBlockList(IEnumerable<String> blockList)
    {
      cloudBlockBlob.PutBlockList(blockList);
    }
    private void GetBlockList()
    {
      IEnumerable<ListBlockItem> listBlockItems =cloudBlockBlob.DownloadBlockList(BlockListingFilter.All);
      foreach (ListBlockItem item in listBlockItems)
      {
        Boolean committed = item.Committed;
        String name = item.Name;
        Int64 size = item.Size;
      }
    }
  9. Add the following method, using the methods added earlier, to the class:
    public static void UseUploadBlockBlobsExample()
    {
      String containerName = "{CONTAINER_NAME}";
      String blobName = "{BLOB_NAME}";
    
      UploadBlockBlobsExample example =new UploadBlockBlobsExample(containerName, blobName);
    
      IEnumerable<String> base64EncodedBlockIds =example.UploadBlocks(20);
      example.PutBlockList(base64EncodedBlockIds);
    
      base64EncodedBlockIds = example.UploadBlocks(10);
      example.GetBlockList();
      example.PutBlockList(base64EncodedBlockIds);
      example.GetBlockList();
    }
  10. Add the following to the configuration section of app.config:
    <appSettings>
      <add key="DataConnectionString" value="DefaultEndpointsProtocol=http;AccountName={ACCOUNT_NAME};AccountKey={ACCOUNT_KEY}"/> 
    </appSettings>

How it works...

In steps 1 through 4, we set up the UploadBlockBlobsExample class. In step 5, we add a member storing a CloudBlockBlob instance that we initialize in the constructor we add in step 6.

The UploadBlocks() method we add in step 7 iterates over the specified number of blocks and invokes the PutBlockFromStream() method. UploadBlocks() passes the loop counter in as a block ID. PutBlockFromStream() converts the integer into the required Base64 format. For the sake of simplicity, we then create a memory stream based on a simple String and invoke the CloudBlockBlob.PutBlob() method to upload the block with the specified Base64 block ID. PutBlockFromStream() returns the Base64 block ID to UploadBlocks() which, in turn, returns an IEnumerable<String> containing the sequence of block IDs.

In step 8, we add a PutBlockList() method that simply defers to the CloudBlockBlob.PutBlockList(). The GetBlockList() method invokes the CloudBlockBlob.DownloadBlockList() method to retrieve the list of committed blocks. We then iterate over the list to observe various properties of it.

In step 9, we add a method that uses the methods we created earlier. We upload 20 blocks and commit them to a block blob. Then we upload another 10 blocks and invoke the GetBlockList() method to verify that we have 20 committed and 10 uncommitted blocks. Finally, we commit the 10 blocks and confirm with another call to GetBlockList() that these blocks have replaced the blob with 20 blocks. We must replace {CONTAINER_NAME} and {BLOB_NAME} with an appropriate container name and blob name.

In step 10, we add the connection string to the app.config configuration file. We must replace {ACCOUNT_NAME} and {ACCOUNT_KEY} with actual values for the account name and access key.

See also

  • We see how to improve upload performance for blobs in the Optimizing blob uploads and downloads recipe in this chapter.
  • We see how to upload page blobs in the Uploading a VHD into a page blob recipe in this chapter.
主站蜘蛛池模板: 遵义县| 灵丘县| 江油市| 海宁市| 黑河市| 墨江| 宾阳县| 五峰| 武定县| 清远市| 盐城市| 桑日县| 龙里县| 建阳市| 托克逊县| 雷山县| 通河县| 九寨沟县| 土默特左旗| 宁强县| 集贤县| 青川县| 瓮安县| 福建省| 凤凰县| 合阳县| 长治市| 开原市| 新丰县| 洛扎县| 镇雄县| 浮梁县| 澄迈县| 富宁县| 敦煌市| 清河县| 娄烦县| 敦煌市| 浦东新区| 芦溪县| 巴林左旗|