小文件直接用file.readalltext/file.writealltext;大文件或逐行处理必须用streamreader/streamwriter配合using;二进制文件只能用readallbytes/writeallbytes,混用会导致乱码、截断或decoderfallbackexception。

小文件直接用 File.ReadAllText 和 File.WriteAllText,别绕弯;大文件或需逐行处理时必须用 StreamReader/StreamWriter 配合 using;二进制内容(图片、PDF、密钥等)只能走 File.ReadAllBytes/File.WriteAllBytes —— 混用会乱码、截断,甚至抛 DecoderFallbackException。
小文本文件:用 File.ReadAllText 和 File.WriteAllText 最省事
适合配置文件、JSON 片段、日志片段等几 MB 以内的纯文本。它们自动处理编码(默认 UTF-8)、打开/关闭流和资源释放,不用写 using 或 try-finally。
-
File.ReadAllText("config.json")抛FileNotFoundException—— 仅当路径存在但文件不存在;若父目录根本不存在,File.WriteAllText直接报DirectoryNotFoundException,它不会尝试创建目录 - 追加内容别手动读-改-写,直接用
File.AppendAllText("log.txt", "[info] start\n") - 编码不匹配?显式传参,比如
File.ReadAllText("data.txt", Encoding.GetEncoding("GB2312"))或Encoding.UTF8 -
File.ReadAllLines("list.txt")返回string[],每行不含换行符;File.ReadLines("huge.log")返回IEnumerable<string></string>,延迟加载,但仍是全遍历 —— 真要跳过前 1000 行,它并不比StreamReader快
大文本文件或逐行处理:必须用 StreamReader + using
几十 MB 以上、边读边过滤、CSV 解析、实时日志扫描等场景,绝不能把整个文件 load 进内存。漏掉 using 就等于没关句柄,下次读写直接失败。
-
StreamReader.ReadLine()返回的字符串不含\r\n,无论原始换行符是\r\n(Windows)、\n(Unix)还是\r(Mac),它都能正确剥离 - 异步读取用
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,配合Read/Write分块操作 - 需要读写结构化二进制数据(比如整数、布尔值、浮点数)?上
BinaryReader/BinaryWriter,它们封装了字节序和类型转换逻辑,比手动BitConverter更安全
最容易被忽略的是:路径合法性检查和编码一致性。File.Exists 不校验路径是否合法(比如含 * 或 ?),而编码错配在开发机上可能“碰巧”显示正常,一到生产环境就乱码——尤其涉及 GBK/GB2312 文件时,务必显式指定 Encoding 参数。










