I am able to copy source folder blob to destination folder blob and delete the source blobs how to copy multiple blobs to source to destination folder and delete source blobs

  1. when I am copying source blobs to destination folder I am unable to give a name for a blob in destination folder

      public async static void CopyDeleteData(ILogger log)
    {
        //copy blobs - from
    
        var ConnectionString = Environment.GetEnvironmentVariable("AzureWebJobsStorage");
        CloudStorageAccount sourceStorageAccount = CloudStorageAccount.Parse(ConnectionString);
        CloudBlobClient sourceCloudBlobClient = sourceStorageAccount.CreateCloudBlobClient();
        CloudBlobContainer sourceContainer = sourceCloudBlobClient.GetContainerReference("Data");        
    
        CloudBlockBlob sourceBlob = sourceContainer.GetBlockBlobReference("SourceFolder/");
        CloudBlockBlob targetBlob = sourceContainer.GetBlockBlobReference("SourceFolder/ArchieveFolder/");
        var resultSegment = sourceContainer.GetDirectoryReference("SourceFolder/");
        var rootDirFolders = resultSegment.ListBlobsSegmentedAsync(true, BlobListingDetails.Metadata,null, null, null, null).Result;
    
        try
        {
            foreach (var blob in rootDirFolders.Results)
            {
            log.LogInformation("Blob    " + blob.Uri);
            await targetBlob.StartCopyAsync(blob.Uri);
    
            }
    
    
        }
        catch (Exception ex)
        {
            log.LogError(ex.Message);
    
            log.LogError( "Error, source BLOB probably has private access only: " + ex.Message);
        }
    
    
        await targetBlob.FetchAttributesAsync();
    
    
        while (targetBlob.CopyState.Status == Microsoft.WindowsAzure.Storage.Blob.CopyStatus.Pending)
        {
            log.LogError("Status: " + targetBlob.CopyState.Status);
            Thread.Sleep(500);
            await targetBlob.FetchAttributesAsync();
        }
    
    
        if (targetBlob.CopyState.Status != Microsoft.WindowsAzure.Storage.Blob.CopyStatus.Success)
        {
    
            log.LogError("Copy failed with status: " + targetBlob.CopyState.Status);
        }
    
    
        await sourceBlob.DeleteAsync();
    
    
        log.LogInformation( "Done.");
    }
    
2

There are 2 answers

0
Hury Shen On

When we use targetBlob.StartCopyAsync(blob.Uri) to copy a blob to the target blob, we should specify the blob name to targetBlob. In you code, you use:

CloudBlockBlob targetBlob = sourceContainer.GetBlockBlobReference("SourceFolder/ArchieveFolder/");

So targetBlob only have the folder directory but not blob name.

Please refer to my code below:

var ConnectionString = "xxxxxx";
CloudStorageAccount sourceStorageAccount = CloudStorageAccount.Parse(ConnectionString);
CloudBlobClient sourceCloudBlobClient = sourceStorageAccount.CreateCloudBlobClient();
CloudBlobContainer sourceContainer = sourceCloudBlobClient.GetContainerReference("data");

CloudBlockBlob sourceBlob = sourceContainer.GetBlockBlobReference("SourceFolder/");
//CloudBlockBlob targetBlob = sourceContainer.GetBlockBlobReference("SourceFolder/ArchieveFolder/");   //please remove this line, get "targetBlob" in the foreach loop
var resultSegment = sourceContainer.GetDirectoryReference("SourceFolder/");
var rootDirFolders = resultSegment.ListBlobsSegmentedAsync(true, BlobListingDetails.Metadata, null, null, null, null).Result;

try
{
    foreach (var blob in rootDirFolders.Results)
    {
        string blobUri = blob.Uri.ToString();
        string blobName = blobUri.Substring(blobUri.IndexOf("SourceFolder/") + 13);
        CloudBlockBlob targetBlob = sourceContainer.GetBlockBlobReference("SourceFolder/ArchieveFolder/" + blobName);
        await targetBlob.StartCopyAsync(blob.Uri);
    }
}
catch (Exception ex)
{
    ........
}

After running the code, we can find three txt files are copied from SourceFolder/ to SourceFolder/ArchieveFolder/ (shown as below two screenshots).

enter image description here enter image description here

0
Alex Gordon On

Keep in mind that the simplest way to do this is with bindings.

You can declaratively bind to your containers/blobs. For example these will allow you to read/write blobs:

enter image description here

And this binding will let you write to the container:

enter image description here

The following example shows how to copy and delete blobs:

using BlobMover.Models;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
using Microsoft.WindowsAzure.Storage.Blob;
using System;
using System.IO;
using System.Threading.Tasks;

namespace BlobMover
{
    public static class BlobMover
    {
        [StorageAccount("Connection")]
        [FunctionName("BlobMover")]
        public static async Task Run(
            [QueueTrigger("%BlobMover:TriggerQueue%")] BlobMessage msg,
            [Blob("{source}-error/{name}", FileAccess.Write)] CloudBlockBlob error,
            [Blob("{destination}/{name}", FileAccess.Write)] CloudBlockBlob @out,
            [Blob("{source}/{name}", FileAccess.Read)] CloudBlockBlob @in,
            ILogger log)
        {
            var trackingId = Guid.NewGuid();

            await @out.StartCopyAsync(@in);
            await @in.DeleteAsync();
        }
    }
}