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:
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));
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));
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With