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.
YoMate, thanks, this actually saved my life, I was almost killing myself... cheers
ReplyDelete