如何使用Golang实现文件内容替换_读取修改再写回文件

文件替换需先读取再安全写回:用os.ReadFile读取,strings.ReplaceAll或regexp进行字符串/正则替换,再通过.tmp临时文件+os.Rename原子更新,避免覆盖丢失。

直接读取文件内容,用字符串或正则替换后写回原文件即可,关键在于避免覆盖、处理编码和错误。

读取文件内容并做字符串替换

使用 os.ReadFile 读取整个文件到内存(适合中小文件),再用 strings.ReplaceAllstrings.Replace 修改:

  • 若需全局替换:用 strings.ReplaceAll(content, "旧文本", "新文本")
  • 若只换前 N 次:用 strings.Replace(content, "旧", "新", N)
  • 注意:Go 字符串是 UTF-8 编码,中文、符号均能正常处理

用正则表达式进行灵活替换

当匹配逻辑复杂(如替换带数字的版本号、特定格式的 URL)时,用 regexp 包:

  • 先编译正则:r := regexp.MustCompile(`v\d+\.\d+\.\d+`)
  • 再替换:r.ReplaceAllString(content, "v2.0.0")r.ReplaceAllFunc(...)
  • 支持分组捕获后引用,例如 r.ReplaceAllStringFunc(content, func(s string) string { return "NEW_" + s })

安全写回原文件(防数据丢失)

不要直接 os.WriteFile(filename, newBytes, 0644) 覆盖——万一出错会丢原文件。推荐两步法:

  • 先写入临时文件:os.WriteFile(filename+".tmp", newBytes, 0644)
  • 再原子替换:os.Rename(filename+".tmp", filename)
  • 若需保留原权限/ModTime,可用 os.Stat 读取后调用 os.Chmodos.Chtimes

完整示例代码(含错误处理)

// 替换文件中所有 "GO_VERSION" 为 "1.22"

data, err := os.ReadFile("config.txt")
if err != nil {
  log.Fatal(err)
}
newData := strings.ReplaceAll(string(data), "GO_VERSION", "1.22")
err = os.WriteFile("config.txt.tmp", []byte(newData), 0644)
if err != nil {
  log.Fatal(err)
}
err = os.Rename("config.txt.tmp", "config.txt")
if err != nil {
  log.Fatal(err)
}