Go 数据存储篇(二):通过 JSON 格式存取文本数据

Go语言精选

共 2883字,需浏览 6分钟

 ·

2020-09-10 20:46

内存存储性能虽好,但是无法持久化存储,并且容量也是有限的,要将大块数据永久保存起来,还是需要借助文件系统和数据库。我们先来看文件存储。

存储数据到文件系统有两种方式,一种是文本格式,比如 CSV、JSON 格式文件,一种是二进制格式,比如 Gob。接下来我们通过三篇教程的篇幅分别进行演示。

首先来看如何通过 JSON 格式保存数据到文件。

我们在上篇教程中已经演示过如何在内存中通过 Go 提供的数据类型处理数据。如果要将处理后的数据保存到文件系统,对于基本类型而言(数字、字符串)直接写入文件即可,而对于数组、切片、字典、结构体这种复合类型,Go 语言官方没有像 PHP 那样直接提供序列化函数,我们可以通过 JSON 编码将其转化为 JSON 格式字符串写入文件(序列化),后面需要用到它们从文件中读取后,可以通过 JSON 解码再将其转化为原来的数据类型(反序列化)。

下面,我们编写一段示例代码 json.go 进行演示:

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
)

// 存放文章信息的 Post 结构体
type Book struct {
    Id int `json:"id"`
    Title string `json:"title"`
    Summary string `json:"summary"`
    Author string `json:"author"`
}

func main()  {
    // 初始化一个字典类型变量
    var books map[int]*Book = make(map[int]*Book)
    book1 := Book{Id: 1, Title: "Go Web 编程", Summary: "Go Web 编程入门指南", Author: "学院君"}
    books[book1.Id] = &book1

    // 通过 JSON 序列化字典数据
    data, _ := json.Marshal(books)

    // 将 JSON 格式数据写入当前目录下的d books 文件(文件不存在会自动创建)
    err := ioutil.WriteFile("books", data, 0644)
    if err != nil {
        panic(err)
    }

    // 从文件 books 中读取数据
    dataEncoded, _ = ioutil.ReadFile("books")
    // 将读取到的数据通过 JSON 解码反序列化为原来的数据类型
    var booksDecoded map[int]*Book
    json.Unmarshal(dataEncoded, &booksDecoded)
    fmt.Printf("%#v", booksDecoded[book1.Id])
}

执行上述代码,输出结果如下,说明 JSON 解码成功:

此外,我们还可以在当前目录下看到新生成了一个 books 文件,文件内容如下:

{"1":{"id":1,"title":"Go Web 编程","summary":"Go Web 编程入门指南","author":"学院君"}}

由此可见,我们已经成功通过 JSON 实现了文本格式数据的序列化和反序列化。

另外,读写文件除了使用 ioutil 包之外,还可以使用 os 包提供的函数,前者更加方便,后者则更加底层,支持的操作和功能更多:

package main

import (
    "encoding/json"
    "fmt"
    "os"
)

// 存放文章信息的 Post 结构体
type Book struct {
    Id int `json:"id"`
    Title string `json:"title"`
    Summary string `json:"summary"`
    Author string `json:"author"`
}

func main()  {
    // 初始化一个字典类型变量
    var books map[int]*Book = make(map[int]*Book)
    book1 := Book{Id: 1, Title: "Go Web 编程", Summary: "Go Web 编程入门指南", Author: "学院君"}
    books[book1.Id] = &book1

    // 通过 JSON 序列化字典数据
    data, _ := json.Marshal(books)

    // 将 JSON 格式数据写入当前目录下的 books 文件
    // err := ioutil.WriteFile("books", data, 0644)
    file1, _ := os.Create("books")
    defer file1.Close()
    _, err := file1.Write(data)
    if err != nil {
        panic(err)
    }

    // 从文件 books 中读取数据
    //dataEncoded, _ = ioutil.ReadFile("books")
    file2, _ := os.Open("books")
    defer file2.Close()
    dataEncoded := make([]bytelen(data))
    file2.Read(dataEncoded)
    // 将读取到的数据通过 JSON 解码反序列化为原来的数据类型
    var booksDecoded map[int]*Book
    json.Unmarshal(dataEncoded, &booksDecoded)
    fmt.Printf("%#v", booksDecoded[book1.Id])
}

注:可将两种文件读写方式类比为 PHP 中的 file_get_contents/file_put_contents 函数与通过 fopen 函数获取文件句柄进行文件读写操作。

运行上述代码,结果和之前完全一致:

(全文完)





推荐阅读



学习交流 Go 语言,扫码回复「进群」即可


站长 polarisxu

自己的原创文章

不限于 Go 技术

职场和创业经验


Go语言中文网

每天为你

分享 Go 知识

Go爱好者值得关注



浏览 85
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报