1
votes

I am trying to copy a file from one storage account to another account using StartCopy method to copy the file. Check the below code.

CloudStorageAccount sourceStorageAccount = CloudStorageAccount.Parse(@"source storage account connection string");
CloudStorageAccount destStorageAccount = CloudStorageAccount.Parse(@"destination storage account connection string");

CloudBlobClient sourceBlobClient = sourceStorageAccount.CreateCloudBlobClient();
CloudBlobClient destBlobClient = destStorageAccount.CreateCloudBlobClient();
var sourceContainer = sourceBlobClient.GetContainerReference("sourceContainer");
var destContainer = destBlobClient.GetContainerReference("destContainer");

CloudBlockBlob sourceBlob = sourceContainer.GetBlockBlobReference("copy.txt");
CloudBlockBlob targetBlob = destContainer.GetBlockBlobReference("copy.txt");

targetBlob.StartCopy(sourceBlob);

But it always return the following error.

Microsoft.WindowsAzure.Storage.StorageException: 'The remote server returned an error: (404) Not Found.'

What am I missing here ?

Note, the same code works perfectly if I try to copy files from one container to another within same storage account.

3
You can take a look at this link.Charles Xu

3 Answers

2
votes

Take a look at the following example on how a copy should be performed (taken from Introducing Asynchronous Cross-Account Copy Blob):

public static void CopyBlobs(
            CloudBlobContainer srcContainer,  
            string policyId, 
            CloudBlobContainer destContainer)
{
    // get the SAS token to use for all blobs
    string blobToken = srcContainer.GetSharedAccessSignature(
                   new SharedAccessBlobPolicy(), policyId);


    var srcBlobList = srcContainer.ListBlobs(true, BlobListingDetails.None);
    foreach (var src in srcBlobList)
    {
        var srcBlob = src as CloudBlob;

        // Create appropriate destination blob type to match the source blob
        CloudBlob destBlob;
        if (srcBlob.Properties.BlobType == BlobType.BlockBlob)
        {
            destBlob = destContainer.GetBlockBlobReference(srcBlob.Name);
        }
        else
        {
            destBlob = destContainer.GetPageBlobReference(srcBlob.Name);
        }

        // copy using src blob as SAS
        destBlob.StartCopyFromBlob(new Uri(srcBlob.Uri.AbsoluteUri + blobToken));
    }
}

Hope it helps!

0
votes

Here is another way to do this using TransferManager.CopyAsync Method

CloudStorageAccount sourceStorageAccount = CloudStorageAccount.Parse(@"source storage account connection string");
CloudStorageAccount destStorageAccount = CloudStorageAccount.Parse(@"destination storage account connection string");

CloudBlobClient sourceBlobClient = sourceStorageAccount.CreateCloudBlobClient();
CloudBlobClient destBlobClient = destStorageAccount.CreateCloudBlobClient();
var sourceContainer = sourceBlobClient.GetContainerReference("sourceContainer");
var destContainer = destBlobClient.GetContainerReference("destContainer");

CloudBlockBlob sourceBlob = sourceContainer.GetBlockBlobReference("copy.txt");
CloudBlockBlob targetBlob = destContainer.GetBlockBlobReference("copy.txt");

TransferManager.CopyAsync(sourceBlob, targetBlob, true).Wait();

TransferManager is under the namespace Microsoft.WindowsAzure.Storage.DataMovement. To get the reference install Microsoft.Azure.Storage.DataMovement in nuget manager.

0
votes

i recently ran into this error trying to copy from /uploads to /raw within a single blob account.

The issue was that the container /raw didn't exist on the destination side within the test environment.

(ie, this error is actually thrown by the destination, not the source)