如何使用Golang写入JSON文件_Golang JSON文件处理方法与实例

1次阅读

最稳妥方式是先用 json.marshal 序列化结构体为字节切片,再用 os.writefile 写入文件;需确保字段导出、添加 json tag、严格检查每一步 Error

如何使用Golang写入JSON文件_Golang JSON文件处理方法与实例

json.Marshal 序列化结构体再写入文件最稳妥

go 标准库不提供直接“一键保存 JSON 到文件”的函数,必须分两步:先序列化为字节切片,再写入文件。跳过 json.Marshal 直接用 json.Encoder 虽可行,但出错时难定位是数据问题还是 IO 问题。

常见错误:结构体字段没加导出(首字母小写),导致序列化后是空对象 {};或忘记处理 json.Marshal 返回的 error,结果写入了 nil 字节流。

  • 确保结构体字段首字母大写,且加上 json tag(如 Username String `json:"username"`
  • 始终检查 json.Marshal 的 error,不要忽略
  • 写文件建议用 os.WriteFile(Go 1.16+),简洁且自动处理 close
data := struct{ Name string `json:"name"` }{Name: "Alice"} b, err := json.Marshal(data) if err != nil {     log.Fatal(err) } err = os.WriteFile("user.json", b, 0644) if err != nil {     log.Fatal(err) }

json.Encoder 流式写入适合大数据或嵌套结构

当你要写入大量 JSON(比如数组元素逐个生成)、或结构体嵌套很深、或需控制缩进/换行时,json.Encoder 更灵活。它直接写入 io.Writer,可接文件、网络连接甚至内存 buffer。

容易踩的坑:忘记调用 encoder.Encode()(不是 EncodeAll),或误以为一次 Encode 能写多个值——它每次只写一个 JSON 值,多次调用会生成多个独立 JSON 对象(非合法 JSON 数组)。

立即学习go语言免费学习笔记(深入)”;

  • 写入数组需手动输出 [],并在元素间加逗号
  • encoder.SetIndent("", " ") 可美化输出(但有性能开销)
  • 如果写入失败,error 发生在 Encode() 调用时,不是 Close()
f, _ := os.Create("users.json") defer f.Close() enc := json.NewEncoder(f) enc.SetIndent("", "  ") enc.Encode(map[string]string{"id": "1", "role": "admin"}) enc.Encode(map[string]string{"id": "2", "role": "user"}) // 注意:这会生成两行独立 JSON,不是 { ... } 包裹的数组

读取 JSON 文件务必检查 json.Unmarshal 的 error

很多人只检查 os.Open 错误,却忽略 json.Unmarshal 失败——比如文件内容是 {name: "bob"}(key 缺少引号),或类型不匹配(JSON 中是字符串,Go 结构体字段却是 int)。

典型现象:程序不报错,但结构体字段全是零值(""0nil),调试时才发现是 unmarshal 失败被静默吞掉了。

  • 永远用 err != nil 判断 json.Unmarshal 是否成功
  • 若 JSON 字段可能缺失或类型不确定,用 map[string]Interface{} 或自定义 UnmarshalJSON 方法
  • 避免用 json.RawMessage 过度延迟解析,除非真需要跳过某段结构校验

注意文件权限与路径,windowslinux 行为一致但路径分隔符要小心

os.WriteFileos.Open 在 Windows 和 Linux 下对路径分隔符都支持 /(Go 运行时自动转换),但硬编码 会导致编译失败或路径错误。另外,文件权限参数(如 0644)在 Windows 上被忽略,但在 Linux/macos 上决定能否读写。

  • 路径拼接统一用 path/filepath.Join,别用字符串 +
  • 写入前确保目录存在,os.WriteFile 不会自动创建父目录,要用 os.MkdirAll
  • 临时测试时避免写到根目录或系统路径,优先用相对路径如 ./data/config.json

最常被忽略的是:JSON 写入后没刷新缓冲区(其实 os.WriteFilejson.EncoderClose 都已处理),但如果你用 bufio.Writer 包装文件,就一定得记得 Flush() ——否则内容可能卡在内存里没落盘。

text=ZqhQzanResources