FileWriter 默认使用平台相关换行符,需统一用 System.lineSeparator() 替代硬编码换行符,并配合 BufferedWriter 使用 newLine() 方法以确保跨平台一致性与性能。

FileWriter 默认写入的是平台相关换行符
直接用 FileWriter 写字符串,换行符会变成当前操作系统默认的(Windows 是 \r\n,Linux/macOS 是 \n),哪怕你显式写了 System.lineSeparator(),如果后续又混用了 \n 或 \r\n,文件最终会混用多种换行风格。这不是 FileWriter 的 bug,而是它本身不处理换行逻辑——它只是把字符原样推给底层流。
必须统一用 System.lineSeparator() 替代硬编码换行符
手动拼接字符串时,别再写 "\n" 或 "\r\n",全部替换成 System.lineSeparator()。尤其注意以下场景:
- 多行字符串拼接:
"line1" + System.lineSeparator() + "line2" - 循环写入每行后追加:
writer.write("data"); writer.write(System.lineSeparator()); - 使用
String.join()时传入:String.join(System.lineSeparator(), lines)
注意:System.lineSeparator() 返回的是 String,不是 char,不能传给 write(int) 单字符方法。
FileWriter 不带缓冲,建议套一层 BufferedWriter
FileWriter 自身没有缓冲,每次 write() 都可能触发一次系统调用,性能差,且不方便按行写入。配合 BufferedWriter 后,既能用 newLine()(它内部自动调用 System.lineSeparator()),又能批量刷盘:
try (FileWriter fw = new FileWriter("out.txt");
BufferedWriter bw = new BufferedWriter(fw)) {
bw.write("first line");
bw.newLine(); // ✅ 安全、跨平台、高效
bw.write("second line");
bw.newLine();
}
关键点:
-
BufferedWriter.newLine()和System.lineSeparator()行为一致,但更简洁 - 不要在
BufferedWriter外再手动写System.lineSeparator(),否则会多出换行 - 关闭时必须确保
BufferedWriter关闭(它会自动 flush 并关闭底层FileWriter)
写入前检查文件是否已有混合换行符
如果目标文件是旧文件,且之前由不同平台或不同程序写入过,直接追加可能破坏一致性。此时应:
- 先读取原文件,用
Files.readAllLines(path, charset)按行读(它自动识别各种换行符) - 修改内容后,统一用
Files.write(path, lines, charset)写回——该方法内部使用System.lineSeparator() - 若必须用
FileWriter追加,先确认原文件末尾是否已有换行;没有就补一个System.lineSeparator(),避免新内容粘在最后一行末尾
跨平台换行的本质不是“选对函数”,而是“全程切断所有隐式换行来源”,包括 IDE 自动换行、Git core.autocrlf、甚至复制粘贴进代码里的不可见符。最容易被忽略的是日志框架或模板引擎偷偷注入的 \n——它们不会理会你的 System.lineSeparator()。

















