Reputation: 3278
I am having below method to copy data to destination storage blob
private static async Task MoveMatchingBlobsAsync(IEnumerable<ICloudBlob> sourceBlobRefs,
CloudBlobContainer sourceContainer,
CloudBlobContainer destContainer)
{
foreach (ICloudBlob sourceBlobRef in sourceBlobRefs)
{
if (sourceBlobRef.Properties.ContentType != null)
{
// Copy the source blob
CloudBlockBlob destBlob = destContainer.GetBlockBlobReference(sourceBlobRef.Name);
try
{
//exception throwed here - StartCopyAsync
await destBlob.StartCopyAsync(new Uri(GetSharedAccessUri(sourceBlobRef.Name, sourceContainer))); /
ICloudBlob destBlobRef = await destContainer.GetBlobReferenceFromServerAsync(sourceBlobRef.Name);
while (destBlobRef.CopyState.Status == CopyStatus.Pending)
{
Console.WriteLine($"Blob: {destBlobRef.Name}, Copied: {destBlobRef.CopyState.BytesCopied ?? 0} of {destBlobRef.CopyState.TotalBytes ?? 0}");
await Task.Delay(500);
destBlobRef = await destContainer.GetBlobReferenceFromServerAsync(sourceBlobRef.Name);
}
Console.WriteLine($"Blob: {destBlob.Name} Complete");
}
catch (Exception e)
{
Console.WriteLine($"Blob: {destBlob.Name} Copy Failed");
}
}
}
}
I am getting below exception, there is no more information
The requested operation is not allowed in the current state of the entity
What may be the cause?
Here is my method to collect blob from the source location
private static async Task<IEnumerable<ICloudBlob>> FindMatchingBlobsAsync(CloudBlobContainer blobContainer,string prefix, int maxrecords,int total)
{
List<ICloudBlob> blobList = new List<ICloudBlob>();
BlobContinuationToken token = null;
do
{
BlobResultSegment segment = await blobContainer.ListBlobsSegmentedAsync(prefix: prefix, useFlatBlobListing: true, BlobListingDetails.None, maxrecords, token, new BlobRequestOptions(), new OperationContext());
token = segment.ContinuationToken;
foreach (var item in segment.Results)
{
blobList.Add((ICloudBlob)item);
if (blobList.Count > total) // total record count is configured
token = null;
}
} while ( token != null);
return blobList;
}
Here is my GetSharedAccessUri
method which returns Uri without any issue
private static string GetSharedAccessUri(string blobName, CloudBlobContainer container)
{
DateTime toDateTime = DateTime.Now.AddMinutes(60);
SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy
{
Permissions = SharedAccessBlobPermissions.Read,
SharedAccessStartTime = null,
SharedAccessExpiryTime = new DateTimeOffset(toDateTime)
};
CloudBlockBlob blob = container.GetBlockBlobReference(blobName);
string sas = blob.GetSharedAccessSignature(policy);
return blob.Uri.AbsoluteUri + sas;
}
This will iterate only 2 levels but not dynamically till the inner levels. I have blob in below hierarchy
--Container
--FolderA
--FolderAA
--FolderAA1
--File1.txt
--File2.txt
--FolderAA2
--File1.txt
--File2.txt
--FolderAA3
--FolderAB
--File8.txt
--FolderAC
--File9.txt
This hierarchy is dynamic
Additional Question: Is there any GUI tool to copy blob data to target storage account?
Upvotes: 3
Views: 4541
Reputation: 21883
UPDATE
According to your description, I modified it in the official sample code. It is already possible to completely copy the data in one container to another account, and the code has been uploaded to Github.
To use this sample code, you need to modify the App.Config
file. Formal use to the production environment needs to be perfected.
https://github.com/Jason446620/BlobContainerCopy
PRIVIOUS
You can refer to the code in this post for copy operation. If the solution in this post does not help you, please let me know and I will continue to follow up to help you solve the problem.
And u can download Azure Storage Explorer is the GUI tool to copy datas.
Upvotes: 1