You need to enable JavaScript to run this app. 使用BlobBaseClient.DownloadToAsync下载Blob仅返回206部分内容的解决方法
优惠活动
大模型
产品
解决方案
定价
更多

使用BlobBaseClient.DownloadToAsync下载Blob仅返回206部分内容的解决方法

问题根因定位

你现在拿到空内容、看到206 Partial Content日志的问题,是三处代码逻辑错误叠加导致的,并非SDK本身的功能缺陷:

  • 成功判断逻辑完全错位:BlobBaseClient.DownloadToAsync本身内置了大文件分块并发下载能力,内部就是靠多次发送范围请求拉取不同分片、拼接成完整内容写入你传入的流对象。整个流程如果没有抛异常,就代表全量Blob已经完整写入,根本不需要靠返回的Response状态码判断是否成功。你硬卡Status == 200的判断,直接把本来成功的下载流程挡在了内容读取分支外面,全程没执行读流的代码,messageJson自然是空的。
  • 流的位置没有重置:MemoryStream写完所有分片内容后,流指针是停在内容末尾位置的,就算进到读内容的分支,不把指针拨回开头,StreamReader从当前位置往后读,也只会读到空字符串。
  • 取消令牌写法不规范:直接new CancellationToken()的写法不符合SDK使用规范,这类写法生成的令牌没有关联任何取消源,虽然不会直接导致下载失败,但属于写法错误。
  • 超大传输块配置冗余:MaximumTransferSize = long.MaxValue的配置完全没必要,SDK本身对单次分片的大小有内部校验逻辑,设置过大的值反而可能触发传输校验异常。

你日志里看到的206状态,是SDK返回的Response对象承载的分片元数据状态,不是单次分片请求的响应,这个状态码本身不代表下载失败。

修正后的可直接运行代码
string messageJson = string.Empty;
try
{
    var blobBaseClient = new BlobBaseClient(_connectionString, _containerName, blobName);
    using var stream = new MemoryStream();
    
    StorageTransferOptions storageTransferOptions = new StorageTransferOptions
    {
        InitialTransferSize = blobInitialChunkSize.Value * 1000000,
        MaximumConcurrency = blobChunkUploadMaxThreadCount.Value,
        // 替换掉原来的long.MaxValue,用合理的分片大小,比如100MB
        MaximumTransferSize = 100 * 1024 * 1024
    };

    BlobRequestConditions blobRequestConditions = new BlobRequestConditions();
    // 只要方法没有抛出异常,就代表全量Blob已经完整写入传入的流
    await blobBaseClient.DownloadToAsync(
        stream, 
        blobRequestConditions, 
        storageTransferOptions, 
        CancellationToken.None);
    
    // 关键操作:把流指针从末尾重置到流开头,否则读取不到任何内容
    stream.Position = 0;
    using StreamReader streamReader = new StreamReader(stream);
    messageJson = await streamReader.ReadToEndAsync();
}
catch (Exception ex)
{
    _logger.LogError(ex, "下载Blob失败,Blob名称:{BlobName}", blobName);
    throw;
}
return messageJson;
落地注意事项
  • 不需要手动判断响应状态码:SDK内部已经做了全量校验,如果出现分片丢失、校验不通过、权限不足等问题,会直接抛出RequestFailedException,不会返回带异常状态的Response对象。
  • 206 Partial Content是正常的分片请求响应:SDK内部发的Range分片请求,本身就会拿到206的状态码,这是HTTP协议的标准行为,分块下载场景下SDK返回的Response状态为206完全正常,不代表下载不完整。
  • 读取流内容前一定要确认流的Position:所有顺序写入的Stream,写入完成后指针都在末尾,不重置位置直接读是MemoryStream使用场景下的常见坑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.09 18:36:04