Sample code for 30+ languages & platforms
Dart

Upload File in Blocks (with Content-MD5 header) and Commit the Block List

See more Azure Cloud Storage Examples

Demonstrates how to upload a file in blocks and then commit the block list. This example includes a Content-MD5 header for each block.

Chilkat Dart Downloads

Dart
import 'package:chilkat/chilkat.dart';

void main() {
  // Azure Blob Service Example: Upload a file in blocks, and then commit the block list.
  // See also: https://msdn.microsoft.com/en-us/library/azure/dd135726.aspx

  // This example requires the Chilkat API to have been previously unlocked.
  // See Global Unlock Sample for sample code.

  final rest = CkRest();

  // Connect to the Azure Storage Blob Service
  final bTls = true;
  final port = 443;
  final bAutoReconnect = true;
  // In this example, the storage account name is "chilkat".
  try {
    rest.connect('chilkat.blob.core.windows.net', port, bTls, bAutoReconnect);
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    return;
  }

  // Provide Azure Cloud credentials for the REST call.
  final azAuth = CkAuthAzureStorage();
  azAuth.accessKey = 'AZURE_ACCESS_KEY';
  // The account name used here should match the 1st part of the domain passed in the call to Connect (above).
  azAuth.account = 'chilkat';
  azAuth.scheme = 'SharedKey';
  azAuth.service = 'Blob';
  // This causes the "x-ms-version: 2021-08-06" header to be automatically added.
  azAuth.xMsVersion = '2021-08-06';
  rest.setAuthAzureStorage(azAuth);

  // Note: The application does not need to explicitly set the following
  // headers: Content-Length, x-ms-date, Authorization.  These headers
  // are automatically set by Chilkat.

  // As the blocks are uploaded, we'll keep an XML block list for the subsequent commit..
  final xml = CkXml();
  xml.tag = 'BlockList';

  // Any type of file can be uploaded in this way.  It can a text file, binary file, anything...
  // This example will upload an XML file that is approximately 275K in size.  It can be downloaded
  // at http://www.chilkatsoft.com/hamlet.xml
  final fac = CkFileAccess();
  fac.openForRead('qa_data/xml/hamlet.xml');
  // Assuming success for the example..

  // We'll upload in 16K blocks (normally a program would upload in larger block sizes than this,
  // but this is just an example...)
  final blockSize = 16384;

  // How many 16K blocks?  (Including 1 for the last partial block)
  final numBlocks = fac.getNumBlocks(blockSize);

  final crypt = CkCrypt2();
  crypt.hashAlgorithm = 'md5';

  final sbResponseBody = CkStringBuilder();
  final uriPath = CkStringBuilder();
  var blockId = '';
  final dataBlock = CkBinData();
  var contentMd5 = '';
  var i = 0;
  while (i < numBlocks) {

    dataBlock.clear();
    try {
      fac.readBlockBd(i, blockSize, dataBlock);
    } on ChilkatException catch (e) {
      print(e.lastErrorText);
      return;
    }

    // Generate a base64 block ID.  
    // (Chilkat provides a helper method named GenBlockId to make this easy)
    // A pre-base64 encoded block ID length of 4 is sufficient in this case because
    // this file certainly won't have more than 99,999 blocks..
    blockId = fac.genBlockId(i, 4, 'base64');

    // Add this blockId to the list of blocks to be committed.
    xml.newChild2('Latest', blockId);

    // Build the URI path
    uriPath.clear();
    uriPath.append('/mycontainer/hamlet.xml?comp=block&blockId=');
    uriPath.append(blockId);

    contentMd5 = crypt.hashBdENC(dataBlock);
    rest.addHeader('Content-MD5', contentMd5);

    // Upload this block..
    sbResponseBody.clear();
    try {
      rest.fullRequestBd('PUT', uriPath.getAsString(), dataBlock, sbResponseBody);
    } on ChilkatException catch (e) {
      print(e.lastErrorText);
      return;
    }

    // Verify that we received a 201 status code.
    if (rest.responseStatusCode != 201) {
      // Examine the request/response to see what happened.
      print('response status code = ${rest.responseStatusCode}');
      print('response status text = ${rest.responseStatusText}');
      print('response header: ${rest.responseHeader}');
      print('response body (if any): ${sbResponseBody.getAsString()}');
      print('---');
      print('LastRequestStartLine: ${rest.lastRequestStartLine}');
      print('LastRequestHeader: ${rest.lastRequestHeader}');
      return;
    }

    i++;
  }

  fac.fileClose();

  // Now commit the blocks.
  // Let's have a look at the XML that will commit the blocks:
  final xmlStr = xml.getXml();
  print(xmlStr);

  // The XML will look like this:

  // <?xml version="1.0" encoding="utf-8" ?>
  // <BlockList>
  //     <Latest>MDAwMA==</Latest>
  //     <Latest>MDAwMQ==</Latest>
  //     <Latest>MDAwMg==</Latest>
  //     <Latest>MDAwMw==</Latest>
  //     <Latest>MDAwNA==</Latest>
  //     <Latest>MDAwNQ==</Latest>
  //     <Latest>MDAwNg==</Latest>
  //     <Latest>MDAwNw==</Latest>
  //     <Latest>MDAwOA==</Latest>
  //     <Latest>MDAwOQ==</Latest>
  //     <Latest>MDAxMA==</Latest>
  //     <Latest>MDAxMQ==</Latest>
  //     <Latest>MDAxMg==</Latest>
  //     <Latest>MDAxMw==</Latest>
  //     <Latest>MDAxNA==</Latest>
  //     <Latest>MDAxNQ==</Latest>
  //     <Latest>MDAxNg==</Latest>
  //     <Latest>MDAxNw==</Latest>
  // </BlockList>

  // --------------------------------------------------------------------------
  // IMPORTANT: Remove the Content-MD5 header previously set in the loop above.
  // --------------------------------------------------------------------------
  rest.removeHeader('Content-MD5');

  // Send the PUT Block List...
  final String responseStr;
  try {
    responseStr = rest.fullRequestString('PUT', '/mycontainer/hamlet.xml?comp=blocklist', xmlStr);
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    return;
  }

  // When successful, the Azure Storage service will respond with a 201 response status code,
  // with no response body.

  if (rest.responseStatusCode != 201) {
    // Examine the request/response to see what happened.
    print('response status code = ${rest.responseStatusCode}');
    print('response status text = ${rest.responseStatusText}');
    print('response header: ${rest.responseHeader}');
    print('response body (if any): $responseStr');
    print('---');
    print('LastRequestStartLine: ${rest.lastRequestStartLine}');
    print('LastRequestHeader: ${rest.lastRequestHeader}');
    return;
  }

  print('Success.');
}