Go语言json包读写JSON文件(非常详细)
Go 语言内置包 encoding/json 的 NewEncoder() 是工厂函数,主要对结构体 Encoder 执行实例化过程,Encoder 是实现 JSON 数据写入文件的结构体,只要调用结构体方法 Encode() 即可实现数据写入,示例如下:

图 1 output.json文件
NewEncoder() 将数据写入 JSON 文件的过程如下:
读取 JSON 文件由工厂函数 NewDecoder() 实例化结构体 Decoder,再由结构体实例化对象调用 Decode() 方法完成数据的读取操作,示例如下:
运行上述代码,运行结果如下图所示:

图 2 运行结果
综上所述,内置包 encoding/json 实现 JSON 文件的数据读写操作如下:
package main import ( "encoding/json" "fmt" "os" ) type PersonInfo struct { Name string `json:"name"` Age int32 `json:"age"` } func main() { // 使用OpenFile()打开文件,设置O_TRUNC模式,每次写入将覆盖原有数据 // 如果不想为OpenFile()设置参数,则可以用Create()代替,实现效果一样 f2, _ := os.OpenFile("output.json", os.O_RDWR|os.O_CREATE|os.O_TRUNC,0755) // 创建PersonInfo类型的切片 p := []PersonInfo{{"David", 30}, {"Lee", 27}} // 实例化结构体Encoder,实现数据写入 encoder := json.NewEncoder(f2) // 将变量p的数据写入JSON文件 // 数据写入必须使用文件内容覆盖,即设置os.O_TRUNC模式,否则导致内容错乱 err := encoder.Encode(p) // 如果err不为空值nil,则说明写入错误 if err != nil { fmt.Printf("JSON写入失败:%v\n", err.Error()) } else { fmt.Printf("JSON写入成功\n") } }运行上述代码,程序运行完成后将在同一目录下创建文件 output.json,文件内容如下图所示,由于代码的变量 p 是 PersonInfo 类型的切片,它转换 JSON 数据将以数组格式写入文件。

图 1 output.json文件
NewEncoder() 将数据写入 JSON 文件的过程如下:
- 使用 os 包创建或打开文件 output.json,文件模式设置为 O_RDWR、O_CREATE 和 O_TRUNC,如果不想为 OpenFile() 设置参数,可以用 Create() 代替,实现效果一样。
- 将 os 包创建或打开的文件作为 encoding/json 包 NewEncoder() 的参数,得到结构体 Encoder 实例化对象,同时创建 PersonInfo 类型的切片,该切片用于写入 JSON 文件,写入数据必须符合 JSON 格式要求。
- 由结构体 Encoder 实例化对象调用结构体方法 Encode() 实现数据写入操作。Encode() 的参数 v 是空接口类型,支持任何数据类型,但参数 v 将会被 encoding/json 的 marshal()(marshal() 将数据转换为 JSON 格式)处理,因此参数 v 的数据必须符合 JSON 格式。
读取 JSON 文件由工厂函数 NewDecoder() 实例化结构体 Decoder,再由结构体实例化对象调用 Decode() 方法完成数据的读取操作,示例如下:
package main import ( "encoding/json" "fmt" "os" ) type PersonInfo struct { Name string `json:"name"` Age int32 `json:"age"` } func main() { // 使用OpenFile()打开文件,设置O_CREATE模式,若文件不存在则创建 // 如果不想为OpenFile()设置参数,则可以用Open()代替,实现效果一样 f1, _ := os.OpenFile("output.json", os.O_RDWR|os.O_CREATE, 0755) // 定义结构体类型的切片 var person []PersonInfo // 实例化结构体Decoder,实现数据读取 data := json.NewDecoder(f1) // 将已读取的数据加载到切片person err := data.Decode(&person) // 如果err不为空值nil,则说明读取错误 if err != nil { fmt.Printf("JSON读取失败:%v\n", err.Error()) } else { fmt.Printf("JSON读取成功:%v\n", person) } // 关闭文件 f1.Close() }分析上述代码发现,JSON 文件的数据读取和写入过程十分相似,只是两者调用不同的函数和结构体方法。JSON 文件的数据读取过程如下:
- 使用 os 包创建或打开文件 output.json,文件模式设置为 O_RDWR 和 O_CREATE,如果不想为 OpenFile() 设置参数,可以用 Open() 代替,实现效果一样。
- 将 os 包创建或打开的文件作为 encoding/json 包 NewDecoder() 的参数,得到结构体 Decoder 实例化对象,同时创建 PersonInfo 类型的切片,该切片用于存储 JSON 文件数据,存储的数据必须与 JSON 数据格式相符。
- 由结构体 Decoder 实例化对象调用结构体方法 Decode() 实现数据读取操作。Decode() 的参数 v 是空接口类型,支持任何数据类型,但参数 v 将会被 encoding/json 的 unmarshal()(unmarshal() 将 JSON 数据转换为 Go 语言数据类型)处理,因此参数 v 的数据必须与 JSON 数据格式相符。
运行上述代码,运行结果如下图所示:

图 2 运行结果
综上所述,内置包 encoding/json 实现 JSON 文件的数据读写操作如下:
- 首先使用 os 包创建或打开 JSON 文件。如果实现数据写入,可根据实际需要设置 O_RDWR、O_CREATE 或 O_TRUNC 模式。如果实现数据读取,则只需设置 O_RDWR 和 O_CREATE 模式。
- 然后将 os 包创建或打开的文件对象作为 encoding/json 的 NewDecoder() 或 NewEncoder() 的参数,得到实例化对象,再由实例化对象调用 Decode() 或 Encode() 实现文件的数据读取或写入操作。
- 最后数据读取或写入是由异常信息 err 表示的,如果异常信息 err 不为空值 nil,则说明读取或写入错误;若为空值 nil,则说明读取或写入成功。