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

使用CsvHelper导出超2GB数据到Azure Blob Storage报Stream too long如何解决

问题原因
  • 你当前的实现是先把整个CSV文件全部写入MemoryStream内存流中,再一次性上传到Azure Blob Storage。MemoryStream本身存在2GB的容量上限,当生成的CSV超过这个阈值时就会触发「Stream was too long」报错。
  • 该实现还会额外占用和文件大小对等的服务器内存,大文件场景下极易出现内存溢出、上传超时等额外问题。
解决方案

核心逻辑是跳过本地内存缓冲全量数据的步骤,直接向Azure Blob的可写流中写入CSV内容,边生成CSV边上传,完全规避内存流的容量限制,同时大幅降低内存占用。

修改后适配原有SDK的代码如下:

public static void EXPORT_CSV(DataTable dt, string fileName, ILogger log)
{
    try
    {
        // 原有存储账号、容器、Blob引用逻辑保持不变
        var cnStorage = Environment.GetEnvironmentVariable("cnStorage");
        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(cnStorage);
        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
        CloudBlobContainer container = blobClient.GetContainerReference("dataexport");
        container.CreateIfNotExists();
        CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName);
        // 可选:设置Blob的ContentType为csv格式
        blockBlob.Properties.ContentType = "text/csv; charset=utf-8";
        // 可选:设置单块上传大小,可根据网络环境调整,范围1MB~100MB
        blockBlob.StreamWriteSizeInBytes = 10 * 1024 * 1024; // 这里设为10MB

        log.LogInformation($"C# BatchDataExportCSVsegnalazioni START CSV生成上传  at: {DateTime.Now}");
        // 直接打开Blob的可写流,不需要本地MemoryStream缓冲
        using (var blobStream = blockBlob.OpenWrite())
        using (var writer = new StreamWriter(blobStream, Encoding.UTF8))
        using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
        {
            csvWriter.Configuration.TypeConverterOptionsCache.GetOptions<DateTime>().Formats = new[] { "dd/MM/yyyy" };
            // 写入表头
            foreach (DataColumn column in dt.Columns)
            {
                csvWriter.WriteField(column.ColumnName);
            }
            csvWriter.NextRecord();
            // 逐行写入数据,写完直接传到Blob,不需要全量存内存
            foreach (DataRow row in dt.Rows)
            {
                for (var i = 0; i < dt.Columns.Count; i++)
                {
                    csvWriter.WriteField(row[i]);
                }
                csvWriter.NextRecord();
            }
            // 手动Flush确保所有数据都写入流
            csvWriter.Flush();
            writer.Flush();
        }
        log.LogInformation($"C# BatchDataExportCSVsegnalazioni END 上传完成  at: {DateTime.Now}");
    }
    catch (Exception ex)
    {
        log.LogError("Error upload BatchDataExportCSVsegnalazioni: " + ex.Message);
        throw;
    }
}
额外优化建议
  • 如果使用的是新版Azure Blob SDKAzure.Storage.Blobs,可以将blockBlob.OpenWrite()替换为blockBlob.OpenWrite(true)方法,逻辑完全一致。
  • 如果数据量特别大,可以对DataTable做分批查询读取,避免一次性把全量数据加载到DataTable中占内存,进一步提升性能。
  • 可以配置断点续传逻辑,避免网络波动导致大文件上传失败需要重传。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 04:00:02