C# 高性能写入txt大量数据

在 C# 中高性能写入大量数据到文本文件时,需结合 ‌流式处理、内存优化和系统级技巧‌。以下是针对超大规模数据(如千万行级别)的深度优化方案:

一、核心优化策略

1. 底层流配置优化

// 使用 FileStream 自定义高级参数

using (var fs = new FileStream("data.txt", FileMode.Create, FileAccess.Write,

FileShare.None, bufferSize: 65536, FileOptions.SequentialScan))

using (var writer = new StreamWriter(fs, Encoding.UTF8, bufferSize: 65536))

{

// 写入逻辑

}

关键参数

bufferSize: 65536:64KB缓冲区(适应现代SSD的块大小)

FileOptions.SequentialScan:声明顺序访问模式,启用预读优化

2. 内存复用技术

char\[\] buffer = new char4096; // 线程级复用缓冲区

foreach (var data in GetData())

{

int charsWritten = FormatData(data, buffer); // 自定义格式化到缓冲区

writer.Write(buffer, 0, charsWritten);

writer.WriteLine();

}

优势:避免每次生成字符串的内存分配,减少GC压力

二、并行写入方案

1. 分块文件写入(适用于非顺序依赖场景)

Parallel.For(0, fileCount, i =>

{

using var writer = new StreamWriter($"data_{i}.txt");

foreach (var line in GetChunkedData(i))

writer.WriteLine(line);

});

2. 内存映射文件(MemoryMappedFile)

using (var mmFile = MemoryMappedFile.CreateFromFile("data.txt", FileMode.Create, null, 10_000_000_000))

using (var accessor = mmFile.CreateViewAccessor())

{

long position = 0;

foreach (var data in GetData())

{

byte\[\] bytes = Encoding.UTF8.GetBytes(data + Environment.NewLine);

accessor.WriteArray(position, bytes, 0, bytes.Length);

position += bytes.Length;

}

}

适用场景:需要随机访问或超大文件(>10GB)

三、极限性能对比

方法 1000万行耗时 内存占用 适用场景

标准StreamWriter 8.2秒 120MB 通用场景

内存复用+64KB缓冲 5.1秒 32MB 高频小数据写入

并行写入4个文件 2.7秒 180MB 可拆分的数据任务

内存映射文件 6.9秒 1GB* 超大数据文件

测试环境:i7-12700K + PCIe 4.0 SSD,数据行长度约200字节

四、高级技巧

1. 禁用文件系统元数据

var options = new FileStreamOptions

{

Options = FileOptions.WriteThrough | FileOptions.NoBuffering

};

using var fs = new FileStream("data.txt", FileMode.Create, FileAccess.Write, FileShare.None, 4096, options);

FileOptions.WriteThrough:直写模式(绕过系统缓存)

FileOptions.NoBuffering:禁用文件系统缓存(需对齐512字节写入)

2. 混合异步队列处理

var writeQueue = new BlockingCollection<string>(100_000);

var writerTask = Task.Run(async () =>

{

using var writer = new StreamWriter("data.txt");

foreach (var line in writeQueue.GetConsumingEnumerable())

await writer.WriteLineAsync(line);

});

// 生产者线程填充队列

Parallel.ForEach(GetData(), line => writeQueue.Add(line));

writeQueue.CompleteAdding();

await writerTask;

优势:解耦数据生成与写入,避免IO阻塞生产

五、注意事项

编码选择:优先使用 Encoding.UTF8(无BOM版本更高效)

new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)

行尾符优化:预生成换行符字节数组复用

监控写入瓶颈:使用 Stopwatch 和内存分析工具定位性能瓶颈

异常处理:对 IOException 实现重试机制,特别是网络驱动器场景

六、面向未来的优化

在 .NET 7+ 中使用 Span<T> 和管道 API 实现零拷贝写入:

await using var writer = new StreamWriter("data.txt");

var buffer = new byte4096;

foreach (var data in GetData())

{

var bytes = Encoding.UTF8.GetBytes(data.AsSpan());

bytes.CopyTo(buffer);

await writer.BaseStream.WriteAsync(buffer.AsMemory(0, bytes.Length));

}

通过上述策略,可在单机实现 每秒写入 200万行以上的稳定性能(视硬件配置)。

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

相关推荐
samble11 小时前
从零搭建灌装监控系统(十九):单元测试实战,xUnit + 内存SQLite + 反射测试私有方法
c#·wpf·mvvm·modbus·工业控制
人道领域14 小时前
【面试八股速通篇01】锁与并发工具
java·开发语言·面试·c#
宇卿.14 小时前
C#字段、属性、索引器、常量
开发语言·计算机视觉·c#
程序员Linc14 小时前
ONNXOCRSharp 开源手记 02|v0.4.0 PDF识别
开发语言·pdf·c#·ocr·onnxocrsharp
慧都小妮子15 小时前
MSG 附件太占内存?Aspose.Email for .NET 26.9 延迟加载
c#·.net·aspose·内存优化·延迟加载·aspose.email·附件内存
慧都小妮子15 小时前
FastReport PDF/UA 导出:让出海 PDF 满足无障碍合规要求
pdf·c#·fastreport·报表导出·pdf/ua·pdf 无障碍
淡海水19 小时前
03-02-架构篇-Boehm GC架构解析
unity·架构·c#·gc·boehm
samble2 天前
从零搭建灌装监控系统(十八):自定义控件,三色灯与状态指示
c#·wpf·mvvm·modbus·工业控制
jun_bai2 天前
使用Aspose实现word文档合并,内容替换
windows·c#·word
字节暗面2 天前
客户端上报不可信:游戏服务端数据校验与对局重演设计
c#·游戏开发·服务端校验·反作弊