14

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?

2
  • Please provide the full Error message Commented Apr 13, 2016 at 13:43
  • 2
    The remote server returned an error: (404) Not Found. --- The specified resource does not exist.
    – shlatchz
    Commented Apr 13, 2016 at 14:11

2 Answers 2

17

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.

3
  • 2
    Another option is to use the Azure Storage Data Movement Library for .NET. This is the library that underlies AzCopy. Take a look at the announcement here: azure.microsoft.com/en-us/blog/… There's also a helpful sample application here: github.com/Azure/azure-storage-net-data-movement/tree/master/… (If you're not familiar with AzCopy, see here: azure.microsoft.com/en-us/documentation/articles/…) Commented Apr 13, 2016 at 15:27
  • 2
    @TamraMyers-Microsoft Is it more efficient than using the standard Microsoft.WindowsAzure.Storage library? Or are they both legit?
    – shlatchz
    Commented Apr 13, 2016 at 16:48
  • 5
    For StartCopyAsync which is used in your code, DataMovement Library isn't more efficient since it's server side copy.However, for downloading, uploading, or sync copy between blobs (download to memory then upload), AzCopy and DataMovement Library are much more efficient than Microsoft.WindowsAzure.Storage library since it's doing the transfer in multiple threads. Commented Apr 13, 2016 at 22:38
10

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);
    }
}
1
  • 1
    This is a really nice clean solution. Worked for me. Commented Aug 26, 2018 at 12:27

Not the answer you're looking for? Browse other questions tagged or ask your own question.