c# 如何读取和写入文件

来源:这里教程网 时间:2026-02-21 17:40:02 作者:

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()
,它自动处理唯一性和清理风险
路径和权限不是附加题,是每次读写前都得过的一关。没处理好,再短的代码也会在生产环境突然失败。

相关推荐