streamreader/streamwriter 读写 txt 文件需明确指定编码(如 encoding.default 或 encoding.getencoding("gbk"))并用 using 管理资源,避免乱码和文件占用;大文件须逐行处理,小文件可用 file.readalltext/writealltext 简化操作。

StreamReader 读取 TXT 文件时编码不匹配会乱码
默认用 Encoding.UTF8 打开文件,但 Windows 记事本保存的 ANSI 编码(其实是系统本地编码,比如 GBK)文件一读就变问号或方块。别猜,先看文件真实编码——用 VS Code 打开右下角点编码名就能确认。
- 明确指定编码:用
new StreamReader("data.txt", Encoding.Default)读系统默认编码;GBK 文件就用Encoding.GetEncoding("GBK") - 避免用无参构造:
new StreamReader("data.txt")在 .NET Core/.NET 5+ 默认 UTF-8,在旧版 .NET Framework 默认系统编码,行为不一致 - 大文件别一次
ReadToEnd():内存暴涨,改用ReadLine()循环逐行处理
StreamWriter 写入 TXT 文件中文乱码或换行符异常
写入中文出 ?,大概率是没传编码参数;换行在 Linux 上显示为 ^M,是因为用了 \r\n(Windows 风格),而目标环境期望 \n。StreamWriter 不自动适配运行环境换行符。
- 必须显式传编码:
new StreamWriter("out.txt", false, Encoding.UTF8),第二个参数false表示不追加(覆盖写) - 换行统一用
WriteLine()方法,它按当前平台输出\r\n或\n;手拼"\n"会导致跨平台显示异常 - 别忘了
Flush()或Close():否则缓冲区内容可能没真正落盘,尤其程序异常退出时
用 using 管理 StreamReader/StreamWriter 是硬性要求
这两个类实现 IDisposable,内部持有文件句柄。不释放会导致文件被占用、后续读写失败,甚至引发 IOException: The process cannot access the file。
- 必须写成
using (var reader = new StreamReader(...)) { ... },哪怕只读一行 - 别在
try里 new 出来、finally里 close ——using更简洁且能保证执行 - 嵌套使用时注意顺序:先开写再开读?不行。要读写同一文件,必须关一个再开另一个,否则 Windows 下直接报错
File.ReadAllText / File.WriteAllText 能替代 StreamReader/StreamWriter 吗
能,但只适合小文件(几 MB 以内)。它们是封装好的快捷方式,底层还是用 StreamReader/StreamWriter,只是帮你省了 using 和编码处理。
- 简单场景直接用:
File.ReadAllText("log.txt", Encoding.UTF8)比手动 new + using 短得多 - 大文件或需流式处理(比如边读边过滤、边写边压缩)必须用原生类,否则内存爆掉
-
File.WriteAllLines()会自动用Environment.NewLine换行,比手动拼更安全
using 就等于留了个锁在文件上。










