Azure File Storage upload with WriteRange and MD5 is KO

Viewed 127

I'm trying to upload a file in azure storage with C# REST API library. I want to be able to upload a file with percentage of upload, so I looked in the documentation and try to achieve this with WriteRange method.

It's working but I'm unable to store the MD5 of the file (and to retrieve it later).

This is my repro case :

static void Main(string[] args)
{
    var storageAccount = CloudStorageAccount.Parse(connectionString);
    var fileClient = storageAccount.CreateCloudFileClient();
    var share = fileClient.GetShareReference(shareReference);
    var rootDir = share.GetRootDirectoryReference();

    var firstFileCloudName = "test/file1.txt";
    var firstFilePath = "c:\\test\\file1.txt";
    var secondFileCloudName = "test/file2.txt";
    var secondFilePath = "c:\\test\\file2.txt";

    // upload first file
    var firstFile = rootDir.GetFileReference(firstFileCloudName);
    firstFile.UploadFromFile(firstFilePath, options: new FileRequestOptions { StoreFileContentMD5 = true });

    // check md5 of first file
    var checkFirstFile = rootDir.GetFileReference(firstFileCloudName);
    if (checkFirstFile.Exists() && checkFirstFile.Properties.ContentMD5 == Convert.ToBase64String(MD5.Create().ComputeHash(File.ReadAllBytes(firstFilePath))))
    {
        Console.WriteLine("First file OK"); // OK
    }

    // upload second file with chunks
    var secondFile = rootDir.GetFileReference(secondFileCloudName);
    Upload(secondFile, secondFilePath);

    // check md5 of second file
    var checksecondFile = rootDir.GetFileReference(secondFileCloudName);
    if (checksecondFile.Exists() && checksecondFile.Properties.ContentMD5 == Convert.ToBase64String(MD5.Create().ComputeHash(File.ReadAllBytes(secondFilePath))))
    {
        Console.WriteLine("Second file OK"); // KO !!!
    }

    // but the file is correctly uploaded because downloaded md5 is OK
    var downloadedFile = rootDir.GetFileReference(secondFileCloudName);
    var memoryStream = new MemoryStream();
    downloadedFile.DownloadToStream(memoryStream);
    if (Convert.ToBase64String(MD5.Create().ComputeHash(memoryStream.ToArray())) == Convert.ToBase64String(MD5.Create().ComputeHash(File.ReadAllBytes(secondFilePath))))
    {
        Console.WriteLine("Second file downloaded OK"); // KO !!!
    }
}

private static void Upload(CloudFile currentFile, string file)
{
    var options = new FileRequestOptions { StoreFileContentMD5 = true };

    long bytesToUpload = new FileInfo(file).Length;
    long fileSize = bytesToUpload;
    currentFile.Create(fileSize);
    var blockSize = 256 * 1024;
    currentFile.StreamWriteSizeInBytes = blockSize;
            
    int index = 1;
    long startPosition = 0;
    long bytesUploaded = 0;
    var allBytes = File.ReadAllBytes(file);
    var ms = new MemoryStream(allBytes);

    do
    {
        var bytesToRead = Math.Min(blockSize, bytesToUpload);
        var blobContents = new byte[bytesToRead];
        ms.Position = startPosition;
        ms.Read(blobContents, 0, (int)bytesToRead);

        var md5 = Convert.ToBase64String(MD5.Create().ComputeHash(new MemoryStream(blobContents)));
        currentFile.WriteRange(new MemoryStream(blobContents), startPosition, md5, options: options);

        bytesUploaded += bytesToRead;
        bytesToUpload -= bytesToRead;
        startPosition += bytesToRead;
        index++;
        double percentComplete = (double)bytesUploaded / fileSize;
        Console.WriteLine("Percent complete = " + percentComplete.ToString("P"));
    }
    while (bytesToUpload > 0);

    currentFile.SetProperties(options: options);
}

Some explainations :

First case, upload with UploadFromFile : it's working and I can store and read the MD5. (I can see in azure portal that MD5 is correctly stored in properties)

Second case, with custom upload, the ContentMD5 is null. (I can see in azure portal that MD5 is not stored in properties)

But when I download the second file and calculate md5, the file is correct so the upload is OK.

How can I store the MD5 in azure file with second upload ? (or change upload way with percentage)

1 Answers

In fact, at the end of upload, I can set the MD5 manually ; I thought it was get only :

currentFile.Properties.ContentMD5 = md5;
currentFile.SetProperties();
Related