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

使用DownloadToFileParallelAsync下载大文件如何追踪下载进度?

Microsoft.Azure.Storage.DataMovement下载进度追踪可行方案

针对DownloadToFileParallelAsync方法的进度追踪需求,以下两种方案均可以保留原有下载性能,实现稳定的进度统计:

方案1:使用库内置TransferContext进度回调

该方案无额外开发成本,完全复用原有下载逻辑,性能无损耗:

  1. 先调用Blob的属性查询接口获取待下载文件的总字节大小
  2. 初始化SingleTransferContext对象,绑定IProgress<TransferStatus>回调
  3. 调用DownloadToFileParallelAsync时传入创建的TransferContext实例

代码示例:

// 获取目标文件总大小
await cloudBlob.FetchAttributesAsync();
long totalSize = cloudBlob.Properties.Length;

var transferContext = new SingleTransferContext
{
    Progress = new Progress<TransferStatus>(status =>
    {
        double progress = (double)status.BytesTransferred / totalSize * 100;
        // 自定义进度处理逻辑
        Console.WriteLine($"下载进度:{progress:F2}%");
    })
};

// 执行下载,传入上下文参数
await blob.DownloadToFileParallelAsync(localPath, FileMode.Create, default, null, transferContext, default);

方案2:自定义进度统计包装Stream

如果需要更细粒度的进度控制,可以通过拦截写入流的方式统计已写入字节,性能损耗可以忽略:

  1. 实现自定义ProgressStream类,包装原生FileStream,在Write方法中累计已写入字节数并触发回调
  2. 调用DownloadToFileParallelAsync的Stream重载版本,传入包装后的ProgressStream对象

自定义Stream实现代码:

public class ProgressStream : Stream
{
    private readonly Stream _baseStream;
    private readonly Action<long> _onWrite;
    private long _writtenBytes;

    public ProgressStream(Stream baseStream, Action<long> onWriteCallback)
    {
        _baseStream = baseStream ?? throw new ArgumentNullException(nameof(baseStream));
        _onWrite = onWriteCallback ?? throw new ArgumentNullException(nameof(onWriteCallback));
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        _baseStream.Write(buffer, offset, count);
        _writtenBytes += count;
        _onWrite(_writtenBytes);
    }

    // 其余Stream成员直接转发到基础流实现即可
    public override bool CanRead => _baseStream.CanRead;
    public override bool CanSeek => _baseStream.CanSeek;
    public override bool CanWrite => _baseStream.CanWrite;
    public override long Length => _baseStream.Length;
    public override long Position { get => _baseStream.Position; set => _baseStream.Position = value; }
    public override void Flush() => _baseStream.Flush();
    public override int Read(byte[] buffer, int offset, int count) => _baseStream.Read(buffer, offset, count);
    public override long Seek(long offset, SeekOrigin origin) => _baseStream.Seek(offset, origin);
    public override void SetLength(long value) => _baseStream.SetLength(value);
}

使用示例:

await cloudBlob.FetchAttributesAsync();
long totalSize = cloudBlob.Properties.Length;

await using var baseFs = new FileStream(localPath, FileMode.Create, FileAccess.Write, FileShare.None);
await using var progressFs = new ProgressStream(baseFs, writtenBytes =>
{
    double progress = (double)writtenBytes / totalSize * 100;
    Console.WriteLine($"下载进度:{progress:F2}%");
});

await blob.DownloadToFileParallelAsync(progressFs, default, null, default, default);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 03:15:00