Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Azure Function Blob Trigger copy file to File Share

Looking for help on how to copy a file from an Azure Blob Storage to a File Share when using an Azure Function Blob Trigger (v3)

I see lots and lots of articles and SO questions on copying from File Share to Blob, but nothing in reverse, and trying to reverse the code samples I've found isn't working out too well

I have come up with a solution, but it's not ideal as I believe it is first downloading the file into memory then uploading it to the File Share:


        [FunctionName("MyBlobTrigger")]
        public async void Run([BlobTrigger("uploads/{name}", Connection = "UploadStorageAccount")]Stream myBlob, string name, ILogger log, CancellationToken cancellationToken)
        {

            ShareClient share = new ShareClient(storageConnection, fileShareName);

            ShareDirectoryClient directory = share.GetRootDirectoryClient();
            ShareFileClient fileShare = directory.GetFileClient(name);

            try
            {
                using (Stream stream = myBlob)
                {
                    fileShare.Create(stream.Length);
                    await fileShare.UploadRangeAsync(new Azure.HttpRange(0, stream.Length), stream);
                }

            }
         }

So this does work, though with these issues:

  1. I think it's downloading first to memory then uploading, would prefer to just transfer the file only within the Azure service, it's possible to have some very large files
  2. I would also prefer to use CloudBlockBlob instead of Stream for my blob, main reason being that at the end of the function I need to delete the file, I can easily do this if using CloudBlockBlob. Problem is I haven't been able to figure out how to do the copy when using it

Any ideas?

EDIT - Final code used from accepted answer:

    [FunctionName("MyBlobTrigger")]
    public async void Run([BlobTrigger("uploads/{name}", Connection = "UploadStorageAccount")]CloudBlockBlob myBlob, string name, ILogger log, CancellationToken cancellationToken)
    {

        ShareClient share = new ShareClient(storageConnection, fileShareName);

        ShareDirectoryClient directory = share.GetRootDirectoryClient();
        ShareFileClient fileShare = directory.GetFileClient(name);

        try
        {

            SharedAccessBlobPolicy sasConstraints = new SharedAccessBlobPolicy
            {
                SharedAccessExpiryTime = DateTime.UtcNow.AddHours(1),
                Permissions = SharedAccessBlobPermissions.Read
            };
            var sasToken = myBlob.GetSharedAccessSignature(sasConstraints);
            var blobSasUrl = $"{myBlob.Uri.AbsoluteUri}{sasToken}";

            fileShare.Create(myBlob.Properties.Length);
            await fileShare.StartCopyAsync(new Uri(blobSasUrl));
like image 494
MikeM Avatar asked Nov 14 '25 18:11

MikeM


1 Answers

To copy the contents of a blob to a file share file, you don't really need to download it first. You can simply make use of Azure Storage's async server-side copy feature.

Essentially you would create a SAS URL for the blob with at least read permission and then use that as a source URL for file copy operation.

I have added some pseudo-code below to show how it can be done.

[FunctionName("MyBlobTrigger")]
public async void Run([BlobTrigger("uploads/{name}", Connection = "UploadStorageAccount")]CloudBlockBlob myBlob, string name, ILogger log, CancellationToken cancellationToken)
{

    //Step 1: Get shared access signature for the blob.
    //var sasToken = myBlob.GetSharedAccessSignature();
    
    //Step 2: Get SAS URL for the blob.
    //var blobSasUrl = $"{myBlob.Uri.AbsoluteUri}{sasToken}";

    ShareClient share = new ShareClient(storageConnection, fileShareName);

    ShareDirectoryClient directory = share.GetRootDirectoryClient();
    ShareFileClient fileShare = directory.GetFileClient(name);

    ShareClient share = new ShareClient(storageConnection, fileShareName);

    ShareDirectoryClient directory = share.GetRootDirectoryClient();
    ShareFileClient fileShare = directory.GetFileClient(name);

    try
    {
        //Step 3: Create empty file based on blob's content length
        //fileShare.Create(myBlob.Properties.Length);
        //Step 4: Copy blob's contents to storage file using async file copy.
        //await fileShare.StartCopyAsync(new Uri(blobSasUrl));
    }
}
like image 189
Gaurav Mantri Avatar answered Nov 17 '25 07:11

Gaurav Mantri



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!