C# 操作Azure Blob存储方法 C#如何上传和下载文件到Blob

1次阅读

azure.storage.blobs上传最简路径是blobclient.uploadasync(),支持自动分块、重试和md5校验;需确保容器存在、权限正确(如sas含w)、容器名全小写合规。

C# 操作Azure Blob存储方法 C#如何上传和下载文件到Blob

Azure.Storage.Blobs 上传文件最简路径

新版 SDK(v12+)已弃用旧的 microsoft.Azure.Storage.Blob,必须用 Azure.Storage.Blobs。上传核心是 BlobClient.UploadAsync(),它会自动处理分块、重试和 MD5 校验(默认关闭)。

常见错误:AuthenticationFailed 多因连接字符串过期或 SAS Token 权限不足(缺 w 权限);ResourceNotFound 常因容器名未提前创建或大小写不匹配(容器名全小写)。

  • 确保容器存在:调用 blobServiceClient.GetBlobContainerClient("mycontainer").CreateIfNotExistsAsync()
  • 上传本地文件:await blobClient.UploadAsync("path/to/file.txt", new BinaryData(File.ReadAllBytes("file.txt")))
  • 流式上传更省内存:using var stream = File.OpenRead("file.txt"); await blobClient.UploadAsync(stream);
  • 若需设置 ContentType,传 BlobHttpHeadersnew BlobHttpHeaders { ContentType = "text/plain" }

下载 Blob 文件到本地的三种方式

下载本质是读取 BlobClient 的内容流,关键在是否需要完整加载到内存。大文件务必用流式,否则可能 OOM。

  • 直接下载为字节数组(仅适合小文件):var response = await blobClient.DownloadContentAsync(); byte[] data = response.Value.Content.ToArray();
  • 流式保存到磁盘(推荐):using var downloadStream = await blobClient.OpenReadAsync(); using var FileStream = File.Create("downloaded.txt"); await downloadStream.CopyToAsync(fileStream);
  • 带进度回调的下载(需手动分块):用 DownloadToAsync(Stream, Progress<long>, CancellationToken)</long>Progress<long></long> 回调参数是已读字节数

BlobClient 初始化时连接字符串 vs. SAS token vs. Azure AD

初始化 BlobClient 的方式直接影响权限模型和适用场景:

  • 连接字符串:开发调试最快,但含密钥,禁止提交到代码或 git;格式为 DefaultEndpointsProtocol=https;AccountName=xxx;AccountKey=yyy==;EndpointSuffix=core.windows.net
  • SAS token:适合临时授权,URL 中拼接 ?sv=...&st=...&se=...&sr=c&sp=rw&sig=...,注意 sr=c 表示容器级,sp=rw 含读写权限
  • Azure AD(推荐生产):需给应用注册分配 Storage Blob Data Contributor 角色,用 new DefaultAzureCredential() 自动链式获取 token,无需硬编码凭据

上传下载失败时最该检查的三件事

90% 的问题集中在配置、网络和权限层面,而不是代码逻辑本身。

  • 确认存储账户防火墙设置:若开启“选中网络”,需添加客户端 IP 或允许 Azure 服务访问
  • 检查 DNS 解析:ping <accountname>.blob.core.windows.net</accountname> 是否通;国内环境有时需配 https://<accountname>.blob.core.chinacloudapi.cn</accountname>(Azure China)
  • 验证时间同步:SDK 对签名时间敏感,本地系统时间误差超 15 分钟会导致 AuthenticationFailed

实际项目里最容易被忽略的是容器名的隐式规则——它必须全小写、不能含下划线、长度 3–63 字符,且一旦创建无法重命名。上传前用 Regex.IsMatch(containerName, @"^[a-z0-9]([a-z0-9-]{1,61}[a-z0-9])?$") 校验能省去很多排查时间。

text=ZqhQzanResources