在Golang的开发场景中,JSON是最常用的数据交换格式之一,很多配置文件、接口返回数据都会采用JSON格式存储。通过Golang标准库的json包,我们可以很方便地实现结构体数据与JSON字符串的相互转换,再结合os包的文件操作能力,就能完成JSON文件的读写操作。
核心概念说明
在开始编写代码前,需要先明确两个核心概念:
- 序列化:指将Golang中的结构体、切片等内存数据转换为JSON格式的字符串或字节流的过程,对应json包的Marshal方法。
- 反序列化:指将JSON格式的字符串或字节流转换为Golang中对应的结构体、切片等数据类型的过程,对应json包的Unmarshal方法。
定义待操作的结构体
首先我们需要定义一个结构体,用于映射JSON数据的结构,同时通过结构体标签指定JSON字段的名称,避免Golang结构体字段名和JSON字段名不一致的问题。
package main
import (
"encoding/json"
"fmt"
"os"
)
// 定义用户结构体,json标签指定序列化后的字段名
type User struct {
Name string `json:"name"` // 用户名
Age int `json:"age"` // 用户年龄
Email string `json:"email"` // 用户邮箱
}
实现JSON数据序列化并写入文件
序列化过程会将User结构体实例转换为JSON字节流,之后我们可以将这些字节流写入到本地JSON文件中。
func writeJSONToFile(filename string) error {
// 创建用户数据切片
users := []User{
{Name: "张三", Age: 25, Email: "zhangsan@ipipp.com"},
{Name: "李四", Age: 30, Email: "lisi@ipipp.com"},
}
// 序列化切片为JSON字节流,第二个参数用于格式化输出,缩进为两个空格
data, err := json.MarshalIndent(users, "", " ")
if err != nil {
return fmt.Errorf("序列化数据失败: %v", err)
}
// 将JSON字节流写入文件,权限设置为0644,允许所有者读写,其他用户只读
err = os.WriteFile(filename, data, 0644)
if err != nil {
return fmt.Errorf("写入文件失败: %v", err)
}
fmt.Println("JSON文件写入成功")
return nil
}
实现从JSON文件读取数据并反序列化
反序列化过程会先读取JSON文件的全部内容,再将字节流转换为对应的Golang数据结构。
func readJSONFromFile(filename string) error {
// 读取JSON文件的全部内容
data, err := os.ReadFile(filename)
if err != nil {
return fmt.Errorf("读取文件失败: %v", err)
}
// 定义用于接收数据的切片
var users []User
// 反序列化JSON字节流到切片
err = json.Unmarshal(data, &users)
if err != nil {
return fmt.Errorf("反序列化数据失败: %v", err)
}
// 打印读取到的数据
fmt.Println("读取到的用户数据:")
for _, user := range users {
fmt.Printf("姓名: %s, 年龄: %d, 邮箱: %sn", user.Name, user.Age, user.Email)
}
return nil
}
完整调用示例
我们将上述方法整合到main函数中,完成完整的JSON文件读写流程测试。
func main() {
filename := "users.json"
// 先执行写入操作
err := writeJSONToFile(filename)
if err != nil {
fmt.Printf("写入失败: %vn", err)
return
}
// 再执行读取操作
err = readJSONFromFile(filename)
if err != nil {
fmt.Printf("读取失败: %vn", err)
return
}
}
注意事项
- 结构体字段首字母必须大写,否则json包无法访问到字段,会导致序列化后字段丢失。
- 如果JSON字段名和结构体字段名一致,可以省略json标签,但是建议统一添加标签,提高代码可读性。
- 如果JSON文件中包含结构体没有的字段,反序列化时这些字段会被自动忽略,不会报错。
- 如果JSON数据类型和结构体字段类型不匹配,反序列化时会返回错误,需要提前做好类型校验。