Azure Functions 的 Azure Blob 存储输出绑定

通过输出绑定,可在 Azure Functions 中修改和删除 blob 存储数据。

若要了解设置和配置详细信息,请参阅概述

重要

本文使用选项卡来支持多个版本的 Node.js 编程模型。 v4 模型已正式发布,旨在为 JavaScript 和 TypeScript 开发人员提供更为灵活和直观的体验。 有关 v4 模型工作原理的更多详细信息,请参阅 Azure Functions Node.js 开发人员指南。 要详细了解 v3 和 v4 之间的差异,请参阅迁移指南

Azure Functions 支持两种 Python 编程模型。 定义绑定的方式取决于选择的编程模型。

使用 Python v2 编程模型,可以直接在 Python 函数代码中使用修饰器定义绑定。 有关详细信息,请参阅 Python 开发人员指南

本文同时支持两个编程模型。

示例

可使用以下 C# 模式之一来创建 C# 函数:

  • 独立辅助角色模型:编译的 C# 函数,该函数在独立于运行时的工作进程中运行。 需要独立工作进程才能支持在 LTS 和非 LTS 版 .NET 和 .NET Framework 上运行的 C# 函数。 独立工作进程函数的扩展使用 Microsoft.Azure.Functions.Worker.Extensions.* 命名空间。
  • 进程内模型:编译的 C# 函数,该函数在与 Functions 运行时相同的进程中运行。 在此模型的变体中,可以使用 C# 脚本运行 Functions,该脚本主要用于 C# 门户编辑。 进程内函数的扩展使用 Microsoft.Azure.WebJobs.Extensions.* 命名空间。

以下示例是一个 C# 函数,该函数在独立工作进程中运行,并将 blob 触发器与 blob 输入和 blob 输出 blob 绑定配合使用。 在 测试-采样-触发 容器中创建blob会触发该函数。 它从 test-samples-input 容器读取文本文件,并基于已触发文件的名称在输出容器中创建一个新的文本文件。

using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

namespace SampleApp
{
    public static class BlobFunction
    {
        [Function(nameof(BlobFunction))]
        [BlobOutput("test-samples-output/{name}-output.txt")]
        public static string Run(
            [BlobTrigger("test-samples-trigger/{name}")] string myTriggerItem,
            [BlobInput("test-samples-input/sample1.txt")] string myBlob,
            FunctionContext context)
        {
            var logger = context.GetLogger("BlobFunction");
            logger.LogInformation("Triggered Item = {myTriggerItem}", myTriggerItem);
            logger.LogInformation("Input Item = {myBlob}", myBlob);

            // Blob Output
            return "blob-output content";
        }
    }
}

本部分包含以下示例:

HTTP 触发器,使用 OutputBinding (Java)

下面的示例显示了一个 Java 函数,该函数使用 HttpTrigger 注释来接收包含 blob 存储容器中某个文件的名称的一个参数。 然后,BlobInput 注释读取该文件并将其作为 byte[] 传递给该函数。 BlobOutput 注释绑定到 OutputBinding outputItem,然后,函数使用后者来将输入 blob 的内容写入到所配置的存储容器中。

  @FunctionName("copyBlobHttp")
  @StorageAccount("Storage_Account_Connection_String")
  public HttpResponseMessage copyBlobHttp(
    @HttpTrigger(name = "req", 
      methods = {HttpMethod.GET}, 
      authLevel = AuthorizationLevel.ANONYMOUS) 
    HttpRequestMessage<Optional<String>> request,
    @BlobInput(
      name = "file", 
      dataType = "binary", 
      path = "samples-workitems/{Query.file}") 
    byte[] content,
    @BlobOutput(
      name = "target", 
      path = "myblob/{Query.file}-CopyViaHttp")
    OutputBinding<String> outputItem,
    final ExecutionContext context) {
      // Save blob to outputItem
      outputItem.setValue(new String(content, StandardCharsets.UTF_8));

      // build HTTP response with size of requested blob
      return request.createResponseBuilder(HttpStatus.OK)
        .body("The size of \"" + request.getQueryParameters().get("file") + "\" is: " + content.length + " bytes")
        .build();
  }

队列触发器,使用函数返回值 (Java)

下面的示例显示了一个 Java 函数,该函数使用 QueueTrigger 注释来接收包含 blob 存储容器中某个文件的名称的一个消息。 然后,BlobInput 注释读取该文件并将其作为 byte[] 传递给该函数。 BlobOutput 注释绑定到函数返回值,然后,运行时使用后者来将输入 blob 的内容写入到所配置的存储容器中。

  @FunctionName("copyBlobQueueTrigger")
  @StorageAccount("Storage_Account_Connection_String")
  @BlobOutput(
    name = "target", 
    path = "myblob/{queueTrigger}-Copy")
  public String copyBlobQueue(
    @QueueTrigger(
      name = "filename", 
      dataType = "string",
      queueName = "myqueue-items") 
    String filename,
    @BlobInput(
      name = "file", 
      path = "samples-workitems/{queueTrigger}") 
    String content,
    final ExecutionContext context) {
      context.getLogger().info("The content of \"" + filename + "\" is: " + content);
      return content;
  }

Java 函数运行时库中,对其值将写入 Blob 存储中对象的函数参数使用 @BlobOutput 注释。 参数类型应为 OutputBinding<T>,其中 T 是任意原生 Java 类型或普通的 Java 对象(POJO)。

以下示例显示队列触发的 TypeScript 函数,该函数创建 blob 的副本。 包含要复制的 blob 名称的队列消息触发该函数。 新 Blob 名为 {originalblobname}-Copy

import { app, input, InvocationContext, output } from '@azure/functions';

const blobInput = input.storageBlob({
    path: 'samples-workitems/{queueTrigger}',
    connection: 'MyStorageConnectionAppSetting',
});

const blobOutput = output.storageBlob({
    path: 'samples-workitems/{queueTrigger}-Copy',
    connection: 'MyStorageConnectionAppSetting',
});

export async function storageQueueTrigger1(queueItem: unknown, context: InvocationContext): Promise<unknown> {
    return context.extraInputs.get(blobInput);
}

app.storageQueue('storageQueueTrigger1', {
    queueName: 'myqueue-items',
    connection: 'MyStorageConnectionAppSetting',
    extraInputs: [blobInput],
    return: blobOutput,
    handler: storageQueueTrigger1,
});

以下示例显示队列触发的 JavaScript 函数,该函数创建 blob 的副本。 包含要复制的 blob 名称的队列消息触发该函数。 新 Blob 名为 {originalblobname}-Copy

const { app, input, output } = require('@azure/functions');

const blobInput = input.storageBlob({
    path: 'samples-workitems/{queueTrigger}',
    connection: 'MyStorageConnectionAppSetting',
});

const blobOutput = output.storageBlob({
    path: 'samples-workitems/{queueTrigger}-Copy',
    connection: 'MyStorageConnectionAppSetting',
});

app.storageQueue('storageQueueTrigger1', {
    queueName: 'myqueue-items',
    connection: 'MyStorageConnectionAppSetting',
    extraInputs: [blobInput],
    return: blobOutput,
    handler: (queueItem, context) => {
        return context.extraInputs.get(blobInput);
    },
});

下面的示例演示如何创建传入 Blob 的副本作为 PowerShell 函数的输出。

在函数的配置文件 (function.json) 中, 元数据属性用于指定 trigger 属性中的输出 Blob 名称。

注意

为了避免无限循环,请确保输入和输出路径不同。

{
  "bindings": [
    {
      "name": "myInputBlob",
      "path": "data/{trigger}",
      "connection": "MyStorageConnectionAppSetting",
      "direction": "in",
      "type": "blobTrigger"
    },
    {
      "name": "myOutputBlob",
      "type": "blob",
      "path": "data/copy/{trigger}",
      "connection": "MyStorageConnectionAppSetting",
      "direction": "out"
    }
  ],
  "disabled": false
}

下面是 PowerShell 代码:

# Input bindings are passed in via param block.
param([byte[]] $myInputBlob, $TriggerMetadata)
Write-Host "PowerShell Blob trigger function Processed blob Name: $($TriggerMetadata.Name)"
Push-OutputBinding -Name myOutputBlob -Value $myInputBlob

以下示例显示了 Blob 输入和输出绑定。 该示例取决于使用的是 v1 还是 v2 Python 编程模型

代码可创建 Blob 的副本。

import logging
import azure.functions as func

app = func.FunctionApp()

@app.function_name(name="BlobOutput1")
@app.route(route="file")
@app.blob_input(arg_name="inputblob",
                path="sample-workitems/test.txt",
                connection="<BLOB_CONNECTION_SETTING>")
@app.blob_output(arg_name="outputblob",
                path="newblob/test.txt",
                connection="<BLOB_CONNECTION_SETTING>")
def main(req: func.HttpRequest, inputblob: str, outputblob: func.Out[str]):
    logging.info(f'Python Queue trigger function processed {len(inputblob)} bytes')
    outputblob.set(inputblob)
    return "ok"

特性

进程内独立工作进程 C# 库都使用特性来定义函数。 C# 脚本改用 function.json 配置文件,如 C# 脚本指南中所述。

BlobOutputAttribute 构造函数采用以下参数:

参数 说明
BlobPath Blob 的路径。
Connection 指定如何连接到 Azure Blob 的应用设置或设置集合的名称。 请参阅连接

在本地开发时,需要将应用程序设置添加到 集合中的 Values中。

修饰符

仅适用于 Python v2 编程模型。

对于使用修饰器定义的 Python v2 函数,blob_inputblob_output 上的以下属性可定义 Blob 存储触发器:

properties 说明
arg_name 表示函数代码中的 Blob 的变量的名称。
path Blob 的路径。对于 blob_input 修饰器,它是 blob 读取。 对于 blob_output 修饰器,它是输入 Blob 的输出或副本。
connection 存储帐户连接字符串。
dataType 对于动态类型化语言,指定基础数据类型。 可能的值为 stringbinarystream。 有关更多详细信息,请参阅触发器和绑定概念

对于使用 function.json 定义的 Python 函数,请参阅“配置”部分。

批注

使用 @BlobOutput 特性可以访问触发函数的 blob。 如果将字节数组与特性一起使用,请将 dataType 设置为 binary。 有关详细信息,请参阅输出示例

配置

仅适用于 Python v1 编程模型

下表说明了可以在传递给 options 方法的 output.storageBlob() 对象上设置的属性。

properties 说明
路径 Blob 容器的路径。
连接 指定如何连接到 Azure Blob 的应用设置或设置集合的名称。 请参阅连接

下表解释了在 function.json 文件中设置的绑定配置属性。

properties 说明
type 必须设置为 blob
direction 对于输出绑定,必须设置为 out用法部分中已阐述异常。
name 表示函数代码中的 Blob 的变量的名称。 设置为 $return 可引用函数返回值。
路径 Blob 容器的路径。
连接 指定如何连接到 Azure Blob 的应用设置或设置集合的名称。 请参阅连接

有关完整示例的信息,请参阅示例部分

使用情况

Blob 输出支持的绑定类型取决于函数应用中使用的扩展包版本和 C# 形式。

如果希望函数写入单个 blob,blob 输出绑定可以绑定到以下类型:

类型 说明
string Blob 内容即字符串。 在 blob 内容为简单文本时使用。
byte[] Blob 内容的字节数。
JSON 可序列化类型 表示 JSON blob 内容的对象。 函数尝试将普通的旧 CLR 对象 (POCO) 类型序列化为 JSON 数据。

如果希望函数写入多个 blob,blob 输出绑定可以绑定到以下类型:

类型 说明
T[],其中 T 是单 blob 输出绑定类型之一 包含多个 blob 的内容的数组。 每个条目表示一个 blob 的内容。

对于其他输出方案,请直接从 Azure.Storage.Blob 创建和使用 BlobClientBlobContainerClient 和其他类型 有关使用依赖项注入从 Azure SDK 创建客户端类型的示例,请参阅 “注册 Azure 客户端 ”。

仅当 blob 大小较小时才建议绑定到 stringByte[]。 推荐使用这些类型,因为整个 blob 内容都会加载到内存中。 对于大多数 blob,请使用 StreamBlobClient 类型。 有关详细信息,请参阅并发和内存使用情况

如果尝试绑定到某个存储 SDK 类型时收到了错误消息,请确保已引用正确的存储 SDK 版本

还可使用 StorageAccountAttribute 指定要使用的存储帐户。 如果需要使用一个不同于库中的其他函数的存储帐户,可以执行此操作。 构造函数采用包含存储连接字符串的应用设置的名称。 可以在参数、方法或类级别应用该特性。 以下示例演示类级别和方法级别:

[StorageAccount("ClassLevelStorageAppSetting")]
public static class AzureFunctions
{
    [FunctionName("BlobTrigger")]
    [StorageAccount("FunctionLevelStorageAppSetting")]
    public static void Run( //...
{
    ....
}

要使用的存储帐户按以下顺序确定:

  • BlobTrigger 特性的 Connection 属性。
  • 作为 StorageAccount 特性应用到同一参数的 BlobTrigger 特性。
  • 应用到函数的 StorageAccount 特性。
  • 应用到类的 StorageAccount 特性。
  • 函数应用的默认存储帐户,在 AzureWebJobsStorage 应用程序设置中定义。

使用 @BlobOutput 特性可以访问触发函数的 blob。 如果将字节数组与特性一起使用,请将 dataType 设置为 binary。 有关详细信息,请参阅输出示例

通过直接返回值或使用 context.extraOutputs.set() 来访问 blob 数据。

通过与 function.json 文件中绑定名称参数指定的名称匹配的字符串参数访问 Blob 数据。

可以将函数参数声明为以下类型以写出到 Blob 存储:

  • 字符串为 func.Out[str]
  • 流为 func.Out[func.InputStream]

有关详细信息,请参阅输出示例

连接

connection 属性在应用设置中被设置为键,返回函数运行时用于连接扩展所用存储账户的值。 连接属性设置的值取决于连接类型:

  • 管理身份连接:该 connection 属性是由 <CONNECTION_NAME_PREFIX> 一组设置共享的,这些设置共同定义了基于身份的连接与存储账户。 更多信息请参见 定义身份连接
  • 密钥保管库 引用connection属性设置返回一个 Azure 密钥保管库 引用,指向该 连接字符串 中心维护的位置。 更多信息请参见定义 密钥保管库 连接。
  • App Configuration 引用connection属性设置返回一个 Azure 应用程序配置 引用,返回一个 连接字符串 或 密钥保管库 引用。 更多信息请参见连接文章中的 Azure 应用程序配置
  • Connection string:属性设置返回connection实际存储账户的连接字符串。 由于连接字符串包含共享的秘密密钥,你应尽量考虑使用管理身份连接。 更多信息请参见定义连接。

欲了解更多关于绑定连接的信息,请参见 Azure Functions 中的 Manage connection 。 要获取连接字符串,请执行管理存储帐户访问密钥中显示的步骤。

当你设置为 connection 一个键或前缀命名 AzureWebJobsStorage ,或者设置为空字符串时,绑定扩展会使用默认的主机存储账户。 更多信息请参见 优化存储性能

异常和返回代码

绑定 参考
Blob Blob 错误代码
Blob、表、队列 存储错误代码
Blob、表、队列 故障排除

后续步骤