How to Fix Corrupted File When Using DownloadToStream in Azure Blob Storage

How to Fix Corrupted File When Using DownloadToStream in Azure Blob Storage

I have a case where I need to move a blob file on Azure Storage from one folder to another. My C# code looks like the following:

public static bool Move(string sourceFileName, string destinationFileName)
{
    try
    {
        //Retrieve storage account from connection string.
        CloudStorageAccount storAcc = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("AzureStorageConnectionString"));
        //Create the blob client.
        CloudBlobClient blobClient = storAcc.CreateCloudBlobClient();
        //Retrieve reference to a previously created container.
        CloudBlobContainer container = blobClient.GetContainerReference("AZURE_CONTAINER_NAME");
        //Create the container if it doesn't already exist
        container.CreateIfNotExists();
        // Enable public access to blob
        BlobContainerPermissions permissions = container.GetPermissions();
        if (permissions.PublicAccess == BlobContainerPublicAccessType.Off)
        {
            permissions.PublicAccess = BlobContainerPublicAccessType.Blob;
            container.SetPermissions(permissions);
        }

        sourceFileName = ManipulateFileName(sourceFileName);
        destinationFileName = ManipulateFileName(destinationFileName);

        CloudBlockBlob srcBlob = container.GetBlockBlobReference(sourceFileName);
        CloudBlockBlob destBlob = container.GetBlockBlobReference(destinationFileName);

        if (srcBlob.Exists())
        {
            //Create the destination blob
            using (MemoryStream memoryStream = new MemoryStream())
            {
                srcBlob.DownloadToStream(memoryStream);
                destBlob = container.GetBlockBlobReference(destBlob.Name);
                destBlob.UploadFromStream(memoryStream);
            }
            // Delete the source blob.
            srcBlob.Delete();
        }
        return true;
    }
    catch (Exception ex)
    {
        //log the exception
        return false;
    }
}

The image is moved successfully but when opening it for viewing it is giving black screen which means the image file is corrupted for a reason.

After troubleshooting the issue, I noticed that I should set the MemoryStream position to zero because in the code I'm creating a new instance of the MemoryStream and loading the data to it from another blob stream. So to summarize, I need to add the following line of code:

memoryStream.Position = 0;

The final source code should look like the following:

public static bool Move(string sourceFileName, string destinationFileName)
{
    try
    {
        //Retrieve storage account from connection string.
        CloudStorageAccount storAcc = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("AzureStorageConnectionString"));
        //Create the blob client.
        CloudBlobClient blobClient = storAcc.CreateCloudBlobClient();
        //Retrieve reference to a previously created container.
        CloudBlobContainer container = blobClient.GetContainerReference("AZURE_CONTAINER_NAME");
        //Create the container if it doesn't already exist
        container.CreateIfNotExists();
        // Enable public access to blob
        BlobContainerPermissions permissions = container.GetPermissions();
        if (permissions.PublicAccess == BlobContainerPublicAccessType.Off)
        {
            permissions.PublicAccess = BlobContainerPublicAccessType.Blob;
            container.SetPermissions(permissions);
        }

        sourceFileName = ManipulateFileName(sourceFileName);
        destinationFileName = ManipulateFileName(destinationFileName);

        CloudBlockBlob srcBlob = container.GetBlockBlobReference(sourceFileName);
        CloudBlockBlob destBlob = container.GetBlockBlobReference(destinationFileName);

        if (srcBlob.Exists())
        {
            //Create the destination blob
            using (MemoryStream memoryStream = new MemoryStream())
            {
                srcBlob.DownloadToStream(memoryStream);
                memoryStream.Position = 0;
                destBlob = container.GetBlockBlobReference(destBlob.Name);
                destBlob.UploadFromStream(memoryStream);
            }
            // Delete the source blob.
            srcBlob.Delete();
        }
        return true;
    }
    catch (Exception ex)
    {
        //log the exception
        return false;
    }
}

If you have better solution, please share it with us.

1 Comments

  1. YoMate, thanks, this actually saved my life, I was almost killing myself... cheers

    ReplyDelete
Previous Post Next Post