用 File.ReadAllText
和 File.WriteAllText
快速读写文本文件
这是最直接的方式,适合小到中等大小的文本文件(比如配置、日志、JSON 片段)。它们自动处理编码(默认 UTF-8)、打开/关闭流、异常封装,不用手动管理
StreamReader或
StreamWriter。
常见错误是传入不存在的目录路径导致
DirectoryNotFoundException;或对只读文件调用
WriteAllText抛出
UnauthorizedAccessException。
File.ReadAllText("config.txt") 读取全部内容为 string,若文件不存在会抛
FileNotFoundException
File.WriteAllText("output.txt", "hello\nworld") 覆盖写入,路径中父目录必须已存在
如需追加,改用 File.AppendAllText("log.txt", "[info] start\n")
指定编码:用重载版本,例如 File.ReadAllText("data.txt", Encoding.UTF8)
大文件或逐行处理时用 StreamReader
/ StreamWriter
当文件超过几十 MB,或需要边读边处理(比如过滤日志行、解析 CSV)、或写入过程中要控制换行/缓冲时,应避免一次性加载进内存。此时手动控制流更安全、更灵活。
容易忽略的是未正确释放资源——不加
using块会导致文件句柄长期占用,后续读写失败。 必须用
using包裹,确保
Dispose()被调用:
using (var reader = new StreamReader("huge.log"))
{
string line;
while ((line = reader.ReadLine()) != null)
{
if (line.Contains("[ERROR]")) ProcessError(line);
}
}
写入同理:using (var writer = new StreamWriter("result.csv", append: true))
{
writer.WriteLine($"id,{DateTime.Now:O}");
}
StreamReader.ReadLine()会丢弃换行符;
ReadLineAsync()支持异步,但要注意线程上下文(尤其 UI 应用)
二进制文件读写用 File.ReadAllBytes
和 File.WriteAllBytes
图像、PDF、加密数据等非文本内容必须按字节处理。这些方法不涉及编码转换,原样保留所有字节,比文本方法更底层也更可靠。
误用文本方法处理二进制内容(比如用
ReadAllText读 PNG)会导致乱码、截断或
DecoderFallbackException。
byte[] data = File.ReadAllBytes("photo.jpg") —— 安全读取任意文件为字节数组
File.WriteAllBytes("copy.jpg", data) —— 精确还原,无编码干扰
超大二进制文件(如 GB 级视频)仍需用 FileStream+ 缓冲区循环读写,避免内存溢出
注意路径、权限和并发访问问题
Windows 和 Linux 对路径分隔符、大小写、权限模型的处理不同;多线程/多进程同时读写同一文件极易引发
IOException(“正由另一进程使用”)。
很多人卡在看似简单的路径拼接上,比如硬编码
"C:\temp\file.txt"在 Linux 容器里直接崩掉。 用
Path.Combine("logs", $"app_{DateTime.Today:yyyyMMdd}.log") 构造路径,兼容各平台
检查文件是否存在且可写:if (File.Exists(path) && File.GetAttributes(path).HasFlag(FileAttributes.ReadOnly))并发写入必须加锁或用
FileStream指定
FileShare.None;读多写少场景可用
FileShare.Read临时文件建议用
Path.GetTempFileName(),它自动处理唯一性和清理风险 路径和权限不是附加题,是每次读写前都得过的一关。没处理好,再短的代码也会在生产环境突然失败。
