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

C#使用Microsoft.Azure.Storage.DataMovement下载Azure Blob 2GB以上大文件失败如何解决

大文件下载失败解决方案

你遇到的超时、任务取消、I/O中止三类错误,核心是GB级文件传输时长超过了SDK默认阈值、缺少容错机制,同时原有代码存在配置未生效的问题,具体优化方案如下:

核心问题修正

原有代码实例化了DownloadOptions但调用TransferManager.DownloadAsync时传入了null,所有下载配置完全未生效,是首要导致大文件下载失败的原因。

具体优化措施

  • 调整Blob客户端全局配置:给CloudBlobClient设置更长的单次请求超时,开启指数退避重试策略,应对网络波动
  • 调整DataMovement库核心参数:增大块大小,根据网络情况调整并行下载数,避免大量小请求导致的超时
  • 配置下载超时规则:设置整个下载任务的最大执行时间,覆盖GB级文件的全量下载周期
  • 启用断点续传:持久化保存传输checkpoint,传输中断后可直接从断点续传,无需重新下载全量文件
  • 新增异常捕获逻辑:捕获传输过程中的错误,留存断点信息方便后续续传

优化后代码

using Microsoft.Azure.Storage;
using Microsoft.Azure.Storage.Blob;
using Microsoft.Azure.Storage.DataMovement;
using Microsoft.Azure.Storage.RetryPolicies;
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

namespace SampleDownload
{
    class Program
    {
        // 断点保存路径,传输中断后下次启动自动读取续传
        private static string _checkpointPath = @"D:\transfer_checkpoint.dat";

        static async Task Main(string[] args)
        {
            string accountName = "";
            string accountKey = "";
            string storageConnectionString = "DefaultEndpointsProtocol=https;AccountName=" + accountName + ";AccountKey=" + accountKey;
            CloudStorageAccount account = CloudStorageAccount.Parse(storageConnectionString);
            await Download(account);
        }

        public static async Task<CloudBlockBlob> GetBlob(CloudStorageAccount account)
        {
            CloudBlobClient blobClient = account.CreateCloudBlobClient();
            // 配置Blob客户端超时与重试策略
            blobClient.DefaultRequestOptions = new BlobRequestOptions
            {
                MaximumExecutionTime = TimeSpan.FromHours(1), // 单个请求最大执行时间
                ServerTimeout = TimeSpan.FromMinutes(30), // 服务端超时时间
                RetryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(5), 5) // 指数退避重试,最多重试5次
            };

            Console.WriteLine("\nProvide name of Blob container:");
            string containerName = Console.ReadLine();
            CloudBlobContainer container = blobClient.GetContainerReference(containerName);
            await container.CreateIfNotExistsAsync(); // 替换原有Wait()避免死锁

            Console.WriteLine("\nProvide name of Blob:");
            string blobName = Console.ReadLine();
            CloudBlockBlob blob = container.GetBlockBlobReference(blobName);
            return blob;
        }

        public static async Task Download(CloudStorageAccount account)
        {
            string path = @"D:\test.zip";
            Console.WriteLine("\nTransfer started...");

            // 配置下载参数
            DownloadOptions downloadOptions = new DownloadOptions
            {
                MaximumExecutionTime = TimeSpan.FromHours(24), // 整个下载任务最大执行时间,可根据文件大小调整
                DisableContentMD5Validation = true // 大文件可关闭MD5校验加快速度,需要校验可设为false
            };

            // 读取本地留存的断点(如果存在)
            TransferCheckpoint checkpoint = null;
            if (File.Exists(_checkpointPath))
            {
                using (FileStream fs = File.OpenRead(_checkpointPath))
                {
                    checkpoint = TransferCheckpoint.Deserialize(fs);
                }
            }

            SingleTransferContext transferContext = GetSingleTransferContext(checkpoint);

            CloudBlockBlob sourceObject = await GetBlob(account);
            // 配置DataMovement库核心参数
            TransferManager.Configurations.BlockSize = 8 * 1024 * 1024; // 单个块大小设为8MB,大文件可调整到16-32MB
            TransferManager.Configurations.ParallelOperations = 16; // 并行下载数,根据带宽情况调整,带宽大可设到32

            try
            {
                // 注意这里传入了downloadOptions,原有代码传了null导致配置未生效
                await TransferManager.DownloadAsync(sourceObject, path, downloadOptions, transferContext, CancellationToken.None);
                // 下载完成后删除断点文件
                if (File.Exists(_checkpointPath))
                {
                    File.Delete(_checkpointPath);
                }
                Console.WriteLine("\nTransfer operation complete.");
            }
            catch (Exception ex)
            {
                // 传输出错时保存当前断点
                Console.WriteLine($"\nTransfer failed: {ex.Message}");
                using (FileStream fs = File.OpenWrite(_checkpointPath))
                {
                    transferContext.LastCheckpoint.Serialize(fs);
                }
                Console.WriteLine("Checkpoint saved, next run will resume from current progress.");
                throw;
            }
        }

        public static SingleTransferContext GetSingleTransferContext(TransferCheckpoint checkpoint)
        {
            SingleTransferContext context = new SingleTransferContext(checkpoint);

            context.ProgressHandler = new Progress<TransferStatus>((progress) =>
            {
                Console.Write("\rBytes transferred: {0}", progress.BytesTransferred);
            });

            return context;
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 00:57:03