File.ReadAllText适合小文件一次性读取,但会全量加载内存易OOM;StreamReader配合using适合大文件逐行处理;ReadAllLines返回字符串数组仍占内存;异步场景应选ReadAllTextAsync或ReadLineAsync。

File.ReadAllText 适合小文件一次性读取
直接拿到全部文本内容,最常用也最省事。但要注意它会把整个文件加载进内存,几 MB 以上的文件就容易触发 OutOfMemoryException。
- 默认用 UTF-8 解码,如果文件是 GBK 或 UTF-16,得显式传入
Encoding.GetEncoding("GBK")或Encoding.Unicode - 路径不存在时抛
FileNotFoundException,权限不足时抛UnauthorizedAccessException,建议包在try-catch里 - 示例:
string content = File.ReadAllText(@"C:\log.txt", Encoding.UTF8);
StreamReader 配合 using 读大文件或逐行处理
不一次性加载全文,适合日志分析、CSV 解析等场景。必须用 using 确保流及时释放,否则可能锁住文件或泄漏句柄。
- 构造时同样要指定编码,否则可能乱码,尤其是中文 Windows 上默认 ANSI(即 GBK)的文件
-
ReadLine()返回null表示到末尾,别用while (!sr.EndOfStream)——它在某些网络流或压缩流中不可靠 - 示例:
using (var sr = new StreamReader(@"D:\data.csv", Encoding.Default)) { string line; while ((line = sr.ReadLine()) != null) { ProcessLine(line); } }
File.ReadAllLines 性能不如 StreamReader 但比 ReadAllText 更可控
返回 string[],每行一个元素。看似方便,其实仍会把全部行加载进内存,且额外分配数组对象,GC 压力比 StreamReader 大。
- 适合行数明确、总量可控(比如几百行配置)的场景
- 不支持自定义缓冲区大小,无法跳过前 N 行或只读前 M 行
- 编码错误时整行丢弃(取决于
DecoderFallback设置),不如StreamReader可细粒度控制
异步读取要用 File.ReadAllTextAsync 和 StreamReader.ReadLineAsync
UI 线程或 ASP.NET Core 请求处理中,阻塞式读文件会导致线程挂起。同步方法在 async 方法里直接调用会引发死锁(尤其 WinForms/WPF)。
-
File.ReadAllTextAsync内部已做缓冲优化,但依然不适合超大文件 - 逐行异步推荐
StreamReader的ReadLineAsync,配合await foreach(C# 8+)更简洁 - 注意:.NET Framework 4.5+ 支持,.NET Core 全版本支持;旧项目若用 .NET Framework 4.0,得自己包装
BeginRead
实际用哪一种,关键看文件大小、是否需要逐行逻辑、是否在 UI 或高并发上下文里——不是越“高级”的 API 越好,而是越贴合现场约束的越稳。编码和异常分支比读取本身更容易出问题。










