Go 追加日志时为什么原文件内容被清空
Go 里“追加日志却把原文件清空”,通常不是 WriteString 的问题,而是打开文件时把 os.O_TRUNC 和写权限一起传给了 os.OpenFile。这个标志会在打开普通可写文件时把长度截为 0;os.O_APPEND 只负责让每次写入落到文件末尾,不能抵消截断动作。
- 追加日志的常用组合是
os.O_APPEND|os.O_CREATE|os.O_WRONLY,不要带os.O_TRUNC。 O_CREATE只负责文件不存在时创建,父目录仍必须提前存在。- 写入函数要检查打开、写入和关闭错误;多进程场景还要配合轮转和外部锁策略。
为什么 O_TRUNC 会让“追加”变成覆盖
os.OpenFile 的第二个参数是按位或组合的打开标志。它们的职责不同:O_APPEND 表示写入前定位到文件末尾,O_CREATE 表示文件不存在时创建,O_TRUNC 则表示打开时截断普通可写文件。于是下面这类写法虽然看起来同时包含“追加”和“创建”,但每次打开都会先清空旧内容:
// 错误示例:O_TRUNC 会在写入前把旧日志长度设为 0
f, err := os.OpenFile("service.log", os.O_WRONLY|os.O_CREATE|os.O_APPEND|os.O_TRUNC, 0644)
if err != nil {
return err
}
defer f.Close()
// 这里能写入,但此前的内容已经被截断
_, err = f.WriteString("request finished\n")
return err
所以排查时先搜索 O_TRUNC,再检查是否存在 os.Create 或反复打开文件的封装。os.Create 本身就是“创建并截断”的语义,不能拿来做追加日志。

追加日志应该怎样组合 OpenFile 参数
只追加、不主动覆盖时,最小组合是 O_WRONLY|O_APPEND|O_CREATE。文件存在时保留旧内容并从末尾写入;不存在时创建新文件。权限位 0644 是创建时的请求权限,最终权限还会受到系统 umask 影响。
package main
import (
"fmt"
"os"
)
func appendLog(path, message string) error {
// O_APPEND 保留旧内容并把写入位置放到末尾
f, err := os.OpenFile(path, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
if err != nil {
return fmt.Errorf("open log %q: %w", path, err)
}
defer f.Close() // 函数退出时释放文件描述符
// 统一补换行,避免多条日志粘在同一行
if _, err := f.WriteString(message + "\n"); err != nil {
return fmt.Errorf("write log %q: %w", path, err)
}
return nil
}
这里没有把 O_RDWR 当成默认选项:日志只写不读时,O_WRONLY 更直接。若调用方已经带了换行,可把“补换行”改成约定好的格式化层,避免出现空行。
用三个检查点确认修复没有留下隐患
- 看标志:确认追加函数中没有
O_TRUNC、os.Create或其他会覆盖文件的路径。 - 看路径:确认父目录已经存在;
O_CREATE不会递归创建目录,路径错误应直接返回并记录。 - 看错误:分别处理打开和写入错误;如果对落盘时机有明确要求,再根据场景调用
f.Sync(),不要把它误认为并发锁。
| 标志或方法 | 作用 | 追加日志是否适合 |
|---|---|---|
O_APPEND | 写入定位到文件末尾 | 需要 |
O_CREATE | 不存在时创建文件 | 通常需要 |
O_TRUNC | 打开时清空普通可写文件 | 不要使用 |
os.Create | 创建并截断 | 不要使用 |
并发方面,Go 文档说明同一个 *os.File 的方法可以并发使用,但这不等于多个进程的日志格式天然安全。多个进程同时追加时,尽量让每条记录一次写完,按文件轮转方案协调重命名与重新打开;需要严格顺序或结构化记录时,应交给专门的日志组件或集中采集端。

常见问题
只写 O_APPEND 不写 O_CREATE 可以吗?
可以,但文件不存在时会打开失败。希望日志首次运行自动出现时,应组合 O_CREATE,并确保父目录已创建。
O_APPEND 能保证多条日志绝不交叉吗?
它解决的是每次写入的追加位置,不是完整日志协议。跨进程、超长写入或轮转场景仍要设计记录边界和协调策略。
为什么删掉 O_TRUNC 后日志还是没有写进去?
继续检查 OpenFile 返回的错误、父目录、权限位和实际路径;不要只看 WriteString 的返回值。
记住一句话:O_APPEND 决定“写到哪里”,O_TRUNC 决定“打开时是否清空”。追加日志只需让前者存在,并明确排除后者。
Postman 怎么把登录响应里的 Token 用到下一个请求
- 上一篇
- Postman 怎么把登录响应里的 Token 用到下一个请求
- 下一篇
- RAG 文档分块怎么设置 chunk_size 和 overlap
-
- Golang · Go问答 | 27分钟前 |
- Go slices.Clone 为什么不能深拷贝二维切片
- 406浏览 收藏
-
- Golang · Go问答 | 41分钟前 |
- Go slices.Compact 为什么没有删除全部重复元素
- 385浏览 收藏
-
- Golang · Go问答 | 1小时前 |
- Go 创建多层目录为什么不能只用 Mkdir
- 136浏览 收藏
-
- Golang · Go问答 | 1小时前 | 错误处理 · go · IO · Go eof io.ReadFull UnexpectedEOF
- Go ReadFull 返回 EOF 和 UnexpectedEOF 有什么区别
- 476浏览 收藏
-
- Golang · Go问答 | 1小时前 | Go问答 · I/O排障 · 短写 · Go io.Copy io.Writer io.ErrShortWrite
- Go io.Copy 报 short write 是读端还是写端出错
- 336浏览 收藏
-
- Golang · Go问答 | 2小时前 | go · bufio · 数据读取 · bufio.Scanner Go切片 Scanner.Bytes
- Go 保存 Scanner.Bytes 后为什么前面的行会变化
- 192浏览 收藏
-
- Golang · Go问答 | 2小时前 | HTTPS tls Go 证书 ServerName
- Go 用 IP 连接 HTTPS 为什么会证书域名不匹配
- 364浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- SuperCLUE
- SuperCLUE是权威的中文大语言模型综合评测基准,涵盖语言理解、知识应用、AI Agent智能体及安全性等12项核心能力。通过多轮对话与客观测试,定期发布榜单与技术报告,为模型研发、优化及行业选型提供科学依据。
- 160次使用
-
- C-Eval
- 深入了解C-Eval中文评估套件,涵盖52个学科与4级难度。本文详解其功能特点、Zero-shot/Few-shot使用方法及代码示例,助您全面评测LLM中文理解与泛化能力。
- 88次使用
-
- ClickPrompt
- ClickPrompt是一款专为AI提示词编写者设计的开源在线工具,支持Stable Diffusion绘图、ChatGPT对话及GitHub Copilot代码辅助。提供Prompt自动生成、一键运行、社区分享及可视化优化功能,帮助用户高效获取精准AI输出。
- 47次使用
-
- PromptHero
- PromptHero是专业的AI提示词搜索引擎与优化平台,支持Stable Diffusion、Midjourney等主流模型。提供海量提示词库、分类搜索、在线课程及社区互动,助力用户高效生成高质量AI图像与文本。
- 30次使用
-
- Stable Diffusion Prompt Book
- 深入解析OpenArt推出的Stable Diffusion Prompt Book,这本免费的开源提示词指南涵盖从基础语法到高级技巧,提供风格化词库与参数建议,助您优化AI绘画生成效果。
- 32次使用
-
- Go map 并发写 panic 怎么办:从共享 map 到可控写入路径
- 2026-06-30 123浏览
-
- golang xorm 自定义日志记录器之使用zap实现日志输出、切割日志(最新)
- 2023-02-24 432浏览
-
- Go语言常用的打log方式详解
- 2023-02-24 485浏览
-
- Go语言文件读写操作案例详解
- 2022-12-29 140浏览
-
- Go语言文件开关及读写操作示例
- 2023-02-24 301浏览

