You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C# Azure Function中为Blob添加时间戳后存入归档容器

Azure Function中为归档Blob添加时间戳的实现方案

因为Azure Blob存储没有原生重命名接口,规避方案是将源Blob复制到归档容器的新命名路径下,按需删除原Blob。以下是C#的具体实现:

核心步骤

  • 提取Function触发时间戳(比手动取时间更准确)
  • 拆分原文件名的名称与扩展名,拼接时间戳生成新文件名
  • 将源Blob内容上传/复制到归档容器的新路径
  • 按需删除源容器中的原Blob

完整代码示例

首先确保项目安装Azure.Storage.Blobs NuGet包,然后编写Function:

using Azure.Storage.Blobs;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
using System;
using System.IO;
using System.Threading.Tasks;

public class BlobArchiveFunction
{
    private readonly BlobServiceClient _blobServiceClient;
    private readonly ILogger<BlobArchiveFunction> _logger;

    // 依赖注入BlobServiceClient,复用连接池提升性能
    public BlobArchiveFunction(BlobServiceClient blobServiceClient, ILogger<BlobArchiveFunction> logger)
    {
        _blobServiceClient = blobServiceClient;
        _logger = logger;
    }

    [Function("BlobArchiveFunction")]
    public async Task Run(
        [BlobTrigger("input-container/{name}", Connection = "AzureWebJobsStorage")] Stream blobStream,
        string name,
        DateTimeOffset triggerTime) // 绑定Function触发时间
    {
        try
        {
            // 生成带时间戳的新文件名
            string newFileName;
            var extIndex = name.LastIndexOf('.');
            if (extIndex == -1)
            {
                // 无扩展名的文件
                newFileName = $"{name}{triggerTime.UtcDateTime:yyyy-MM-ddTHH:mm:ss}";
            }
            else
            {
                // 拆分文件名与扩展名,拼接时间戳
                var fileNameWithoutExt = name.Substring(0, extIndex);
                var ext = name.Substring(extIndex);
                newFileName = $"{fileNameWithoutExt}{triggerTime.UtcDateTime:yyyy-MM-ddTHH:mm:ss}{ext}";
            }

            // 获取归档容器客户端,确保容器存在
            var archiveContainer = _blobServiceClient.GetBlobContainerClient("archive-container");
            await archiveContainer.CreateIfNotExistsAsync();

            // 上传到归档容器的新Blob
            var targetBlob = archiveContainer.GetBlobClient(newFileName);
            await targetBlob.UploadAsync(blobStream, overwrite: true);

            // 可选:删除源容器中的原Blob
            // var sourceBlob = _blobServiceClient.GetBlobContainerClient("input-container").GetBlobClient(name);
            // await sourceBlob.DeleteIfExistsAsync();

            _logger.LogInformation($"已归档Blob:原文件名{name} → 新文件名{newFileName}");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "处理Blob时出错,原文件名:{Name}", name);
            throw;
        }
    }
}

关键说明

  1. 触发时间绑定:使用DateTimeOffset triggerTime参数获取Function的触发时间,避免因Function启动延迟导致的时间偏差。
  2. 文件名处理:通过字符串索引拆分文件名与扩展名,避免依赖本地文件系统API。
  3. 上传方式选择:
    • 小Blob场景(本次30分钟一次的文件):直接用流上传即可
    • 大Blob场景:改用服务器端复制更高效,示例代码如下:
      var sourceBlob = _blobServiceClient.GetBlobContainerClient("input-container").GetBlobClient(name);
      await targetBlob.StartCopyFromUriAsync(sourceBlob.Uri);
      
  4. 权限配置:确保AzureWebJobsStorage连接字符串拥有源容器的读取权限、归档容器的写入权限(若需删除源Blob则需额外配置删除权限)。

内容的提问来源于stack exchange,提问作者tony

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 23:04:57