Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copy blob between storage accounts

I'm trying to copy a blob from one storage account to another (In a different location).

I'm using the following code:

var sourceContainer = sourceClient.GetContainerReference(containerId);
var sourceBlob = sourceContainer.GetBlockBlobReference(blobId);
if (await sourceBlob.ExistsAsync().ConfigureAwait(false))
{
    var targetContainer = targetClient.GetContainerReference(containerId);
    await targetContainer.CreateIfNotExistsAsync().ConfigureAwait(false);
    var targetBlob = targetContainer.GetBlockBlobReference(blobId);
    await targetBlob.DeleteIfExistsAsync().ConfigureAwait(false);
    await targetBlob.StartCopyAsync(sourceBlob).ConfigureAwait(false);
}

and I get a "Not Found" error. I do get that the source blob indeed exists. Am I using the wrong command? Is there something I'm missing regarding copying between storage accounts?

like image 240
shlatchz Avatar asked Apr 13 '16 13:04

shlatchz


People also ask

How do I copy blobs between storage accounts?

Copy containers, directories, and blobs Copy all containers, directories, and blobs to another storage account by using the azcopy copy command. This example encloses path arguments with single quotes (''). Use single quotes in all command shells except for the Windows Command Shell (cmd.exe).

Can you share blobs?

Sharing Azure Blob Storage data Let's start by creating a new Azure Data Share account and use that to share an Azure Blob Storage Container. We'll create the Azure Data Share using the Azure portal. Once the deployment is finished, you'll have a new Azure Data Share account.


2 Answers

After playing around with the code, I reached an answer. Copying between storage accounts can only be achieved when the source blob is a uri and not a blob reference. The following code worked:

var sourceContainer = sourceClient.GetContainerReference(containerId);
var sourceBlob = sourceContainer.GetBlockBlobReference(blobId);
// Create a policy for reading the blob.
var policy = new SharedAccessBlobPolicy
{
    Permissions = SharedAccessBlobPermissions.Read,
    SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-15),
    SharedAccessExpiryTime = DateTime.UtcNow.AddDays(7)
};
// Get SAS of that policy.
var sourceBlobToken = sourceBlob.GetSharedAccessSignature(policy);
// Make a full uri with the sas for the blob.
var sourceBlobSAS = string.Format("{0}{1}", sourceBlob.Uri, sourceBlobToken);
var targetContainer = targetClient.GetContainerReference(containerId);
await targetContainer.CreateIfNotExistsAsync().ConfigureAwait(false);
var targetBlob = targetContainer.GetBlockBlobReference(blobId);
await targetBlob.DeleteIfExistsAsync().ConfigureAwait(false);
await targetBlob.StartCopyAsync(new Uri(sourceBlobSAS)).ConfigureAwait(false);

Hope it will help someone in the future.

like image 115
shlatchz Avatar answered Oct 15 '22 23:10

shlatchz


You can also copy blobs between storage accounts by using streams:

var sourceContainer = sourceClient.GetContainerReference(sourceContainer);
var sourceBlob = sourceContainer.GetBlockBlobReference(sourceBlobId);
var targetContainer = targetClient.GetContainerReference(destContainer);
var targetBlob = targetContainer.GetBlockBlobReference(destBlobId);

using (var targetBlobStream = await targetBlob.OpenWriteAsync())
{
    using (var sourceBlobStream = await sourceBlob.OpenReadAsync())
    {
        await sourceBlobStream.CopyToAsync(targetBlobStream);
    }
}
like image 44
Miguel Cruz Avatar answered Oct 16 '22 01:10

Miguel Cruz