小文件用file.readalltext/writealltext最简高效,大文件或逐行处理必须用streamreader/streamwriter配合using,二进制内容一律用readallbytes/writeallbytes,混用会导致乱码、截断或权限异常。

小文件直接用 File.ReadAllText 和 File.WriteAllText,大文件或需逐行处理时必须用 StreamReader/StreamWriter 配合 using,二进制内容一律走 File.ReadAllBytes/File.WriteAllBytes —— 混用会导致乱码、截断或权限异常。
小文本文件:用 File.ReadAllText 和 File.WriteAllText 最快
适合配置、日志片段、JSON 字符串等几 MB 以内的文本。它们自动处理 UTF-8 编码、流打开/关闭和资源释放,不用写 using 或 try-finally。
-
File.ReadAllText("config.json")抛FileNotFoundException如果路径存在但文件不存在;若父目录不存在,File.WriteAllText会直接报DirectoryNotFoundException,不是“创建失败”,而是“根本没尝试创建目录” - 追加内容别硬改
WriteAllText,用File.AppendAllText("log.txt", "[warn] timeout ") - 编码不匹配时显示乱码?显式传
Encoding.UTF8或Encoding.Default,比如File.ReadAllText("data.txt", Encoding.GetEncoding("GB2312")) -
File.ReadAllLines("list.txt")返回string[],每行不含换行符;File.ReadLines("huge.log")返回IEnumerable<string></string>,延迟加载,内存友好但仍是全遍历——真要跳过前 N 行,它不比StreamReader快
大文件或逐行处理:必须用 StreamReader + using
几十 MB 以上文本、边读边过滤、CSV 解析、日志实时扫描等场景,不能把整个文件塞进内存。手动控流是底线,漏掉 using 就等于留着文件句柄不放,下次读写直接失败。
-
StreamReader.ReadLine()返回的字符串不含;如果原始行末是(Mac)或(Unix),它也能正确剥离 - 异步读取用
ReadLineAsync(),但 UI 线程里调用要小心同步上下文死锁,建议搭配ConfigureAwait(false) - 写入时若需追加且不覆盖,构造
StreamWriter要传append: true,否则默认FileMode.Create会清空原文件 - 别手写
sr.Close()或sr.Dispose()——using块编译后自动插入try-finally,手动关容易遗漏异常路径
二进制文件:绕过编码,只认字节
图片、PDF、加密密钥、序列化对象等非文本内容,绝不能用 ReadAllText。文本方法会强行按编码解释字节,结果不是乱码就是抛 DecoderFallbackException。
-
File.ReadAllBytes("photo.jpg")返回byte[],原样保留所有字节;File.WriteAllBytes("backup.bin", data)也是原样写入 - 若需流式处理大二进制文件(如上传分片),用
FileStream配合缓冲区读写,避免一次性分配几百 MB 内存 - 路径中含中文或特殊字符?
Path.Combine("data", "用户配置.bin")比拼接字符串安全,跨平台也稳 - 写入前检查磁盘空间或权限?
File.WriteAllBytes不做预检,失败时才抛IOException或UnauthorizedAccessException,关键路径得自己try-catch
最常被忽略的其实是路径和并发:用 Path.Combine 拼路径,别拼 "C:\folder\" + name;多线程同时写同一文件?File.WriteAllText 没锁,必然丢数据——这时得上 FileStream 手动设 FileShare.None 或外部同步机制。










