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程序集),或安装MimeTypesNuGet包调用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
相关产品推荐
相关产品推荐

