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:
- 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
- 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));
here, you should be able to provide an object of typeCloudBlockBlobas input instead of stream. Please try with that.