c# - 如何从 HTTP 触发的 Azure 函数返回 blob?

标签 c# azure azure-functions azure-blob-storage

我正在尝试使用 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 保留在内存中的字节中)。请注意,我不是绑定(bind)到流,而是绑定(bind)到 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");
        }
   }
}

关于c# - 如何从 HTTP 触发的 Azure 函数返回 blob?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55499499/

相关文章:

c# - 此 RPC 请求中提供的参数过多。最大值为 2100。

azure - 我们可以在 azure 中的多个 Azure openai 服务上使用 azure 负载均衡器吗

azure - 服务总线触发器 : Could not load file or assembly 'Microsoft.Azure.ServiceBus'

azure - 如何使用系统分配的托管标识保护 Azure Function

c# - 如何访问 KnownFolders.DocumentsLibrary

c# - 如何将模式包含在 xml 中

c# - Microsoft.WindowsAPICodePack.Shell音频持续时间未获得

azure - 在 Azure Monitor 中查看 opentelemetry 跟踪

c# - 服务器资源管理器中的 Azure 辅助角色实例中的参数错误

python 连接到 Azure 数据库