azure-functionsazure-blob-storageazure-function-appazure-functions-runtimeazure-function-app-proxy

how to copy blob data and store it in sub directory by using function app


I have a blob in my source virtual folder and I need to move the source blob to another virtual folder and delete the source blob by using azure function app

  1. copying blob data from 1 directory to another

  2. deleting the source blob

please guide me through function-app Code how to copy blobs from one directory to another and delete the blobs

I am facing some Issues while copying the blobs to another directory

 public async static void CopyDelete(ILogger log)
    {
        var ConnectionString = Environment.GetEnvironmentVariable("AzureWebJobsStorage");
        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConnectionString);
        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

        // details of our source file
        CloudBlobContainer sourceContainer = blobClient.GetContainerReference("Demo");            
        var sourceFilePath = "SourceFolder";
        var destFilePath = "SourceFolder/DestinationFolder";
 
        CloudBlockBlob sourceBlob = sourceContainer.GetBlockBlobReference(sourceFilePath);
        CloudBlobDirectory dira = sourceContainer.GetDirectoryReference(sourceFilePath);
        CloudBlockBlob destinationblob = sourceContainer.GetBlockBlobReference(destFilePath);
        try
        {
            var rootDirFolders = dira.ListBlobsSegmentedAsync(true, BlobListingDetails.Metadata, null, null, null, null).Result;

            foreach (var blob in rootDirFolders.Results)
            {
                log.LogInformation("Blob   Detials " + blob.Uri);
               
                //var sas = sourceBlob.GetSharedAccessSignature(new SharedAccessBlobPolicy()
                //{
                //    Permissions = SharedAccessBlobPermissions.Read,
                //    SharedAccessStartTime = DateTimeOffset.Now.AddMinutes(-5),
                //    SharedAccessExpiryTime = DateTimeOffset.Now.AddHours(2)
                //});

                // copy to the blob using the 
                destinationblob = sourceContainer.GetBlockBlobReference(destFilePath);
             //   var sourceUri = new Uri(blob.Uri);
                await destinationblob.StartCopyAsync(blob.Uri);

                // copy may not be finished at this point, check on the status of the copy
                while (destinationblob.CopyState.Status == Microsoft.WindowsAzure.Storage.Blob.CopyStatus.Pending)
                {
                    await Task.Delay(1000);
                    await destinationblob.FetchAttributesAsync();
                    await sourceBlob.DeleteIfExistsAsync();
                }
            }

            if (destinationblob.CopyState.Status != Microsoft.WindowsAzure.Storage.Blob.CopyStatus.Success)
            {
                throw new InvalidOperationException($"Copy failed: {destinationblob.CopyState.Status}");
            }
        }
        catch (Exception ex)
        {

            throw ex;
        }
        
    }

Solution

  • If you want to copy blob and delete them, please refer to the following steps

    1. list blobs with prefix. The prefix is used to filters the results to return only blobs whose names begin with the specified prefix
     private static async  Task< List<BlobItem>> ListBlobsHierarchicalListing(BlobContainerClient container,
                string? prefix, int? segmentSize)
            {
                string continuationToken = null;
                var blobs = new List<BlobItem>();
                try
                {
                    do
                    {
                        var resultSegment = container.GetBlobsByHierarchyAsync(prefix: prefix, delimiter: "/")
                            .AsPages(continuationToken, segmentSize);
    
                        await foreach (Page<BlobHierarchyItem> blobPage in resultSegment)
                        {
    
                            foreach (BlobHierarchyItem blobhierarchyItem in blobPage.Values)
                            {
                                if (blobhierarchyItem.IsPrefix)
                                {
    
                                    Console.WriteLine("Virtual directory prefix: {0}", blobhierarchyItem.Prefix);
                                    var result = await ListBlobsHierarchicalListing(container, blobhierarchyItem.Prefix, null).ConfigureAwait(false);
                                    blobs.AddRange(result);
                                }
                                else
                                {
                                    Console.WriteLine("Blob name: {0}", blobhierarchyItem.Blob.Name);
                                    
                                    blobs.Add(blobhierarchyItem.Blob);
                                }
                            }
    
                            Console.WriteLine();
    
                            // Get the continuation token and loop until it is empty.
                            continuationToken = blobPage.ContinuationToken;
                        }
    
    
                    } while (continuationToken != "");
                    return blobs;
                }
                catch (RequestFailedException e)
                {
                    Console.WriteLine(e.Message);
                    Console.ReadLine();
                    throw;
                }
                
            }
    
    1. Copy and deltet
    private static async Task CopyAndDeltet(BlobItem item, BlobContainerClient des, BlobContainerClient source, string newFolder, string sasToken) {
    
                try
                {
                    var sourceBlobUrl = source.GetBlobClient(item.Name).Uri.ToString() + "?" + sasToken;
                    var desblobName = newFolder + item.Name.Substring(item.Name.IndexOf("/"));
                    var operation = await des.GetBlobClient(desblobName).StartCopyFromUriAsync(new Uri(sourceBlobUrl)).ConfigureAwait(false);
                    var response = await operation.WaitForCompletionAsync().ConfigureAwait(false);
                    if (response.GetRawResponse().Status == 200)
                    {
                        await source.GetBlobClient(item.Name).DeleteAsync().ConfigureAwait(false);
                    }
                }
                catch (Exception)
                {
    
                    throw;
                }
            }
            private static string generateSAS(StorageSharedKeyCredential cred, string containerName, string blobName) {
                var sasBuilder = new BlobSasBuilder()
                {
                    BlobContainerName = containerName,
                    BlobName = blobName,
                    StartsOn = DateTime.UtcNow.AddMinutes(-2),
                    ExpiresOn = DateTime.UtcNow.AddHours(1)
                };
                sasBuilder.SetPermissions(BlobSasPermissions.Read);
                return sasBuilder.ToSasQueryParameters(cred).ToString();
            }
    

    For more details, please refer to here , here and here

    Besides, please note that if you want to copy a large number of blob or large size blob, the Azure function is not a good choice. Azure function just can be used to run some short time tasks. I suggest you use Azure data factory or Azcopy.