如何使用Golang读取JSON文件_Golang encoding/json文件解析实践

正确读取JSON文件需先用os.ReadFile加载字节再json.Unmarshal,注意错误处理、BOM处理、结构体字段导出与json tag、空值类型匹配、大文件流式解析及编码转换。

如何使用golang读取json文件_golang encoding/json文件解析实践

直接用 json.Unmarshal 读取文件内容会 panic,必须先读文件再解码

很多人写成这样:

data := []byte("config.json")
json.Unmarshal(data, &cfg)

——这其实只是把字符串字面量当 JSON 解析了,根本没读文件。正确流程是两步:先用 os.ReadFile(Go 1.16+)或 ioutil.ReadFile(旧版)加载文件字节,再传给 json.Unmarshal

  • os.ReadFile 返回 []byteerror,必须检查错误,空文件或权限不足都会导致失败
  • 不要对文件内容做任何字符串拼接或截断,json.Unmarshal 要求输入是合法 UTF-8 编码的完整 JSON 文本
  • 如果 JSON 文件带 BOM(比如 Windows 记事本保存的),json.Unmarshal 会报 invalid character 'ï' looking for beginning of value,需提前 strip

结构体字段必须导出且加 json: tag 才能被解码

Go 的 json 包只能设置导出字段(首字母大写),且默认按字段名匹配。如果 JSON 键名是 user_name,而结构体字段叫 UserName,不加 tag 就无法映射。

  • 使用 json:"user_name" 显式指定键名,支持别名、忽略字段(json:"-")、omitempty(空值不序列化)
  • 嵌套结构体字段也要导出,否则整个嵌套对象会被跳过,不会报错但值为零值
  • 如果 JSON 中有字段在结构体里不存在,默认忽略;想捕获未知字段,可加一个 json.RawMessage 类型的兜底字段

处理数组、空值、混合类型时,interface{} 不够用,优先用具体类型或自定义 UnmarshalJSON

遇到 JSON 数组如 "tags": ["go", "json"],用 []string 直接接收最安全;但如果 API 返回有时是字符串、有时是数组(常见于弱类型后端),硬转会 panic。

Detect GPT

Detect GPT

一个Chrome插件,检测您浏览的页面是否包含人工智能生成的内容

下载

  • 避免无脑用 map[string]interface{}[]interface{},类型丢失后后续逻辑难维护、易出错
  • 对不确定字段,定义一个字段类型实现 UnmarshalJSON([]byte) error 方法,内部判断 json.Unmarshal 失败后尝试其他解析路径
  • 空字段(null)对应指针或 sql.NullString 等可空类型;普通值类型(如 int)遇到 null 会解码失败

大文件别用 json.Unmarshal,改用 json.Decoder 流式解析

os.ReadFile 把几百 MB 的 JSON 一次性读进内存,不仅慢,还可能 OOM。这时应打开文件句柄,用 json.NewDecoder 边读边解。

  • json.NewDecoder(f).Decode(&v) 每次只解一个顶层 JSON 值(对象或数组),适合日志行、NDJSON 格式
  • 如果是单个巨型 JSON 对象,无法流式解码整个结构,但可用 decoder.Token() 手动跳过不需要的字段,减少内存占用
  • 注意文件编码:标准 json 包只支持 UTF-8,若文件是 UTF-16,需先用 golang.org/x/text/encoding 转换

实际项目里最容易被忽略的是错误处理粒度——不是只检查 os.ReadFile 是否成功,而是要区分「文件不存在」、「权限拒绝」、「JSON 语法错误」、「字段类型不匹配」这四类问题,它们对应的修复方式完全不同。

https://www.php.cn/faq/2010241.html

发表回复

Your email address will not be published. Required fields are marked *