如何通过Azure功能从Blob存储流式传输二进制文件



我正试图通过使用带有HTTP触发器的Azure函数,通过Azure API管理从Blob存储获取二进制文件。应该如何实现Azure功能以达到尽可能小的内存占用?

这个实现是可行的,但它似乎需要大量内存,这会导致在处理太多并发请求时出现内存不足的异常:

public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = "dbrevisions/{dbRevision}")] HttpRequestMessage request,
[Blob("typedatadev/typedata_{dbRevision}.db", FileAccess.Read)] Stream blobStream,
string dbRevision,
ILogger log)
{
var memoryBlobStream = new MemoryStream();
blobStream.CopyTo(memoryBlobStream);
var result = new FileStreamResult(memoryBlobStream, "application/octet-stream");
result.FileStream.Flush();
result.FileStream.Seek(0, SeekOrigin.Begin);
return result;
}

这将结束到状态502(也没有"刷新"调用(:

public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = "dbrevisions/{dbRevision}")] HttpRequestMessage request,
[Blob("typedatadev/typedata_{dbRevision}.db", FileAccess.Read)] Stream blobStream,
string dbRevision, ILogger log)
{
var result = new FileStreamResult(blobStream, "application/octet-stream");
result.FileStream.Flush();
result.FileStream.Seek(0, SeekOrigin.Begin);
return result;
}

这也会失败:

var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StreamContent(blobStream)
};
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
return response;

为了最小化内存占用,我喜欢下面的内容。请注意,我不是绑定到流,而是绑定到ICloudBlob实例(幸运的是,C#函数支持多种类型的blob输入绑定(并返回开放流。使用内存探查器对其进行了测试,即使对于大的Blob,也能很好地工作,没有内存泄漏。

注意:您不需要寻求流位置0或刷新或处置(处置将在响应端自动完成(;

using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Azure.Storage.Blob;
namespace TestFunction1
{
public static class MyFunction
{
[FunctionName("MyFunction")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "dbrevisions/{dbRevision}")] HttpRequest req,
[Blob("typedatadev/typedata_{dbRevision}.db", FileAccess.Read, Connection = "BlobConnection")] ICloudBlob blob,
string dbRevision,
ILogger log)
{
var blobStream = await blob.OpenReadAsync().ConfigureAwait(false);
return new FileStreamResult(blobStream, "application/octet-stream");
}
}
}

这个问题是在2020年提出的,我在.net6 VisualStudio 2022上看到了一篇为我的代码寻找相同解决方案的帖子。因此才有了最新的图书馆。

现在我正在尝试读取一个pfx证书文件,该文件以blob的形式存储在Azure容器上。此容器和blob访问是私有的。

我正在连接到Azure存储帐户,然后找到该文件,然后从Azure中获取作为内存流的文件,最后将其作为X509Certificate2证书对象返回。

这是我的最后一个代码,测试合格。

using Azure.Storage.Blobs;
using Microsoft.Extensions.Logging;
using System;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
namespace ConfigEncryption
{
internal static class CloudStorage
{
//Connection string of the Azure Storage Account - Fonud at the storageaccount|Access keys - Show the keys
const string connectionString = "DefaultEndpointsProtocol=https;AccountName=storageaccountname;AccountKey=thelongkeyvaluewithfewslahesinit;EndpointSuffix=core.windows.net";
const string containerName = "yourcontainername";
const string certName = "Your_Certificate.pfx";const string password = "the_certificate_password";

public static async Task<X509Certificate2> GetCertAsync(ILogger log)
{
try
{
log.LogInformation("Connecting to cloud storage to fetch the certificate");
BlobServiceClient blobServiceClient = new BlobServiceClient(connectionString);
BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);
BlobClient blobClient = containerClient.GetBlobClient(certName);
byte[] certData; 
if (await blobClient.ExistsAsync())
{
var memorystream = new MemoryStream();
blobClient.DownloadTo(memorystream);
certData = memorystream.ToArray();
X509Certificate2 cert = new X509Certificate2(certData, password);
log.LogInformation("Found the certificate on cloud storage.");
return cert;
}
log.LogError("Error: Cerificate not found in the container");
}
catch(Exception ex)
{
log.LogError($"Error: Getting certificate from Cloud storage. Exception Details :{ex.Message}");
}
return null;
}
}

}

我希望它能帮助到别人,快乐编码!

问候,

Rakesh

最新更新