environment.newline仅表示当前系统默认换行符,读取跨平台文本需手动标准化为"\n";推荐用replace("\r\n","\n").replace("\r","\n")统一处理;writeline()自动适配平台,避免硬编码换行符。

用 Environment.NewLine 生成当前平台换行符,但读取时不能依赖它
很多开发者误以为 Environment.NewLine 能自动“适配”输入文本的换行格式——其实它只反映**当前运行环境**的默认换行符(Windows 是 "\r\n",Linux/macOS 是 "\n"),和你读进来的文件无关。读取跨平台文本时,必须主动识别并标准化。
读取时统一转成 "\n" 最省事也最安全
无论源文件是 "\r\n" 还是 "\n",甚至混用(比如 "\r\n\r\n\n"),统一替换成单个 "\n" 后再处理,能避免后续逻辑(如按行分割、正则匹配)出错。
- 用
text.Replace("\r\n", "\n").Replace("\r", "\n")即可覆盖所有常见情况(Windows、Linux、旧 Mac) - 不要只用
text.Replace("\r\n", "\n"):遗漏仅含"\r"的老式 Mac 文本,或纯"\n"中夹杂"\r" - 如果性能敏感且确定来源只有 CRLF/LF,可用
string.Split(new[] { "\r\n", "\n", "\r" }, StringSplitOptions.None),但注意Split会丢弃空行信息,不如先替换再Split('\n')
StreamReader 默认已处理换行符,但行为有隐含前提
StreamReader.ReadLine() 确实会自动识别 "\r\n"、"\n"、"\r" 并返回不带换行符的字符串——但它**只对逐行读取有效**。一旦你用 ReadToEnd() 拿到完整字符串,换行符原样保留,仍需手动清洗。
- 推荐场景:逐行处理日志、配置、CSV 等文本 → 直接用
ReadLine(),不用管换行符差异 - 避坑点:用
ReadToEnd()后调Split('\n')→ 可能切出带"\r"的行尾,导致后续 trim 失效或正则匹配失败 - 编码注意:确保
StreamReader构造时指定了正确编码(如new StreamReader(path, Encoding.UTF8)),否则 BOM 或乱码可能干扰换行符识别
写入时别硬写 "\r\n",优先用 StreamWriter.WriteLine()
硬编码 "\r\n" 会让程序在 Linux 上输出 Windows 风格换行,违反平台惯例;而直接拼 "\n" 又可能让 Windows 用户用记事本打开时显示为一行。最稳妥的方式是交给 StreamWriter 处理:
-
sw.WriteLine("hello")会自动使用Environment.NewLine,输出符合当前平台习惯的换行符 - 如果明确需要跨平台一致(比如生成 HTTP 响应体、JSON 文件),才显式用
"\n"——但必须文档注明,并确保所有消费方都接受 LF - 避免
sw.Write("hello\r\n"):绕过StreamWriter的换行逻辑,失去平台适配能力
"\r\n",若等到 UI 层再处理,可能已被 HTML 渲染或日志框架截断。该清洗的地方,一步到位。










