
Windows 记事本仅识别 \r\n 作为换行符,而 Go 默认使用 \n(LF),导致多行内容显示为一行;本文详解如何通过手动写入 \r\n 或使用标准库工具实现跨平台换行兼容。
windows 记事本仅识别 `\r\n` 作为换行符,而 go 默认使用 `\n`(lf),导致多行内容显示为一行;本文详解如何通过手动写入 `\r\n` 或使用标准库工具实现跨平台换行兼容。
在 Go 中向文本文件写入内容时,若期望在 Windows 系统的记事本(Notepad.exe)中正确显示多行,必须注意换行符的平台差异。Unix/Linux/macOS 使用单个换行符 \n(Line Feed, LF),而 Windows 传统上要求回车+换行组合 \r\n(Carriage Return + Line Feed, CRLF)。记事本严格依赖 \r\n 进行换行渲染——若仅写入 \n,它会将所有内容显示为连续的一行,尽管 WordPad、VS Code 等现代编辑器能智能识别 LF 并正常换行。
在你的示例代码中:
n, err := io.WriteString(f, "Hello World\n") n, err = io.WriteString(f, "Goodbye\n")
虽然逻辑上写了两行,但实际写入的是 Hello World\nGoodbye\n,记事本无法解析 \n,因此显示为 Hello WorldGoodbye。
✅ 解决方案一:显式使用 \r\n 直接替换换行符即可:
n, err := io.WriteString(f, "Hello World\r\n")
if err != nil {
log.Fatal(err)
}
n, err = io.WriteString(f, "Goodbye\r\n")
if err != nil {
log.Fatal(err)
}✅ 解决方案二:使用 fmt.Fprintln(推荐)fmt.Fprintln 会自动调用 io.WriteString 并追加平台相关的行尾符(由 runtime.GOOS 决定),但在 Windows 下默认仍为 \n ——注意:这不是跨平台安全的默认行为。更稳妥的方式是结合 fmt.Fprintf 显式控制:
fmt.Fprintf(f, "Hello World\r\n") fmt.Fprintf(f, "Goodbye\r\n")
✅ 解决方案三:封装为可复用函数(兼顾可读性与兼容性)
func writeLine(w io.Writer, s string) error {
_, err := io.WriteString(w, s+"\r\n")
return err
}
// 使用示例
writeLine(f, "Hello World")
writeLine(f, "Goodbye")⚠️ 重要注意事项:
- 不要依赖 os.Create 后未检查 err 的习惯写法;每次 io.WriteString 或 fmt 操作后都应校验错误。
- 若需真正跨平台(如生成供不同系统读取的日志),可按目标环境动态选择换行符:
lineEnd := "\n" if runtime.GOOS == "windows" { lineEnd = "\r\n" } io.WriteString(f, "Hello World"+lineEnd) - 避免混用 \n 和 \r\n 在同一文件中,否则可能导致部分编辑器解析异常。
总结:Go 本身不强制平台特定换行,开发者需主动适配目标环境。对 Windows 分发文本文件,统一使用 \r\n 是最简单可靠的实践;长期项目建议封装 I/O 辅助函数,提升可维护性与兼容性。










