使用MemoryStream生成CSV字符串仅获半量数据的问题排查
问题分析与解决方案
你的代码出现CSV内容截断的核心原因有两点:
- 写入缓存未同步到流:
CsvWriter和StreamWriter都有内部缓存机制,你在csvWriter的using块内直接读取MemoryStream时,大量数据还滞留在缓存中,并未写入到内存流里。 - 流操作顺序错误:
FlushAsync()被放在了csvWriter的using块之后,此时csvWriter已经被释放,缓存数据无法被正常写入到StreamWriter。
修正后的完整代码
var records = new List<CSVDto>(); // 为records赋值 var csvConfig = new CsvConfiguration(CultureInfo.InvariantCulture) { HasHeaderRecord = true, Delimiter = "," }; using (var mem = new MemoryStream()) { // 开启leaveOpen: true,确保StreamWriter释放时不关闭MemoryStream using (var writer = new StreamWriter(mem, Encoding.UTF8, leaveOpen: true)) { using (var csvWriter = new CsvWriter(writer, csvConfig)) { await csvWriter.WriteRecordsAsync(records); // 先刷新CsvWriter的缓存到StreamWriter await csvWriter.FlushAsync(); } // 刷新StreamWriter的缓存到MemoryStream await writer.FlushAsync(); // 重置内存流指针到起始位置(ToArray()不受位置影响,但属于良好编程习惯) mem.Position = 0; // 读取完整的CSV字符串 var csvString = Encoding.UTF8.GetString(mem.ToArray()); } }
关键修改说明
leaveOpen: true参数:避免StreamWriter释放时关闭MemoryStream,保证后续能正常读取流内容。- 提前刷新缓存:在
csvWriter生命周期内调用FlushAsync(),强制将缓存数据写入到StreamWriter;再通过writer.FlushAsync()把数据同步到MemoryStream。 - 重置流位置:虽然
mem.ToArray()会返回流的全部字节,但重置指针是通用流操作的规范,避免后续操作出现异常。
内容的提问来源于stack exchange,提问作者weeraa
相关产品推荐
相关产品推荐

