本文介绍了如何从HTTP触发的Azure函数返回blob?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在尝试使用Azure函数从Blob存储返回文件。按照现在的情况,我已经让它工作了,但是它的工作效率很低,它将整个blob读入内存,然后将其写回。这对小文件有效,但是一旦它们变得足够大,效率就会非常低。
如何让我的函数直接返回blob,而不必将其完全读取到内存中?
以下是我目前使用的内容:
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, Binder binder, TraceWriter log)
{
// parse query parameter
string fileName = req.GetQueryNameValuePairs()
.FirstOrDefault(q => string.Compare(q.Key, "name", true) == 0)
.Value;
string binaryName = $"builds/{fileName}";
log.Info($"Fetching {binaryName}");
var attributes = new Attribute[]
{
new BlobAttribute(binaryName, FileAccess.Read),
new StorageAccountAttribute("vendorbuilds")
};
using (var blobStream = await binder.BindAsync<Stream>(attributes))
{
if (blobStream == null)
{
return req.CreateResponse(HttpStatusCode.NotFound);
}
using(var memoryStream = new MemoryStream())
{
blobStream.CopyTo(memoryStream);
var response = req.CreateResponse(HttpStatusCode.OK);
response.Content = new ByteArrayContent(memoryStream.ToArray());
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = fileName };
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
return response;
}
}
}
我的function.json
文件:
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get",
"post"
]
},
{
"name": "$return",
"type": "http",
"direction": "out"
}
],
"disabled": false
}
我既不是C#开发人员,也不是Azure开发人员,所以我想不起这些东西。
推荐答案
我这样做是为了最大限度地减少内存占用(不需要在内存中以字节为单位保留完整的BLOB)。注意,我没有绑定到流,而是绑定到一个ICloudBlob
实例(幸运的是,C#函数支持几种风格的blob input binding)并返回开放流。使用内存探查器对其进行了测试,即使对于大型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 = "video/{fileName}")] HttpRequest req,
[Blob("test/{fileName}", FileAccess.Read, Connection = "BlobConnection")] ICloudBlob blob,
ILogger log)
{
var blobStream = await blob.OpenReadAsync().ConfigureAwait(false);
return new FileStreamResult(blobStream, "application/octet-stream");
}
}
}
这篇关于如何从HTTP触发的Azure函数返回blob?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!