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

Azure Blob文件上传:BlobContainerClient与BlobClient该如何选择?

问题描述

需求是将本地带层级结构的文件上传至Azure Blob容器并保持原目录结构。

本地目录结构:

MyFiles 
   -- Folder1
     -- file.txt
     -- img.jpg
   -- Folder2
      -- file2.json
      -- test.png

期望Azure容器中的结构:

Container
     MyFiles 
           -- Folder1
             -- file.txt
             -- img.jpg
           -- Folder2
              -- file2.json
              -- test.png

当前实现代码(已修正语法错误):

var sasCred = new AzureSasCredentials("sasurl");
var container = new BlobContainerClient(new Uri("containerUrl"), sasCred);

var allFiles = Directory.GetFiles("MyFilesFolderPath", "*", SearchOption.AllDirectories);

foreach(var file in allFiles)
{
   var cloudFilePath = file.Replace("MyFilesFolderPath", string.Empty);
   var fullPath= $"MyFiles{cloudFilePath}";

  using(var s = new MemoryStream(File.ReadAllBytes(file)))
  {
     await container.UploadBlobAsync(fullPath, s); 
  }
}

当前代码已实现目录结构同步,但文件ContentType始终显示为application/octet-stream而非对应类型。已知需通过BlobClient设置ContentType,但不确定是否需要替换或结合使用BlobContainerClient。

解决方案

不需要替换BlobContainerClient,两种方式均可实现正确设置ContentType的需求:

方式一:直接通过UploadBlobAsync重载配置ContentType

调用UploadBlobAsync时,传入BlobUploadOptions指定ContentType,可根据文件扩展名自动匹配对应MIME类型:

var sasCred = new AzureSasCredentials("sasurl");
var container = new BlobContainerClient(new Uri("containerUrl"), sasCred);

var allFiles = Directory.GetFiles("MyFilesFolderPath", "*", SearchOption.AllDirectories);

foreach(var file in allFiles)
{
   var cloudFilePath = file.Replace("MyFilesFolderPath", string.Empty);
   var fullPath= $"MyFiles{cloudFilePath}";

   // 根据扩展名获取对应ContentType
   var fileExtension = Path.GetExtension(file).ToLowerInvariant();
   var contentType = fileExtension switch
   {
       ".txt" => "text/plain",
       ".jpg" => "image/jpeg",
       ".json" => "application/json",
       ".png" => "image/png",
       // 可扩展更多扩展名映射
       _ => "application/octet-stream"
   };

   var uploadOptions = new BlobUploadOptions
   {
      HttpHeaders = new BlobHttpHeaders
      {
         ContentType = contentType
      }
   };

   using(var s = new MemoryStream(File.ReadAllBytes(file)))
   {
      await container.UploadBlobAsync(fullPath, s, uploadOptions); 
   }
}

若不想手动维护映射,可使用System.Web.MimeMapping.GetMimeMapping(file)(需引用System.Web程序集),或安装MimeTypes NuGet包调用MimeTypes.GetMimeType(file)自动获取。

方式二:通过BlobClient上传并配置属性

先通过BlobContainerClient获取目标文件的BlobClient,再调用其UploadAsync方法设置ContentType,适合需要额外配置Blob元数据、缓存策略等场景:

var sasCred = new AzureSasCredentials("sasurl");
var container = new BlobContainerClient(new Uri("containerUrl"), sasCred);

var allFiles = Directory.GetFiles("MyFilesFolderPath", "*", SearchOption.AllDirectories);

foreach(var file in allFiles)
{
   var cloudFilePath = file.Replace("MyFilesFolderPath", string.Empty);
   var fullPath= $"MyFiles{cloudFilePath}";

   var blobClient = container.GetBlobClient(fullPath);
   var fileExtension = Path.GetExtension(file).ToLowerInvariant();
   var contentType = fileExtension switch
   {
       ".txt" => "text/plain",
       ".jpg" => "image/jpeg",
       ".json" => "application/json",
       ".png" => "image/png",
       _ => "application/octet-stream"
   };

   using(var s = new MemoryStream(File.ReadAllBytes(file)))
   {
      await blobClient.UploadAsync(s, new BlobHttpHeaders { ContentType = contentType });
   }
}

两种方式均能保留原有目录结构同步逻辑,推荐方式一(代码更简洁);若需对Blob进行更多自定义配置,选择方式二更灵活。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 03:15:46