encoding/gob
包用于管理由gob
组成的流(stream),这是一种在编码器(encoder)和解码器(decoder)之间进行交换的二进制数据,这种数据原本是为序列化以及数据传输而设计的,但它也可以用于对数据进行持久化,并且为了让用户能够方便地对文件进行读写,编码器和解码器一般都会分别包裹起程序的写入器以及读取器。代码清单6-4展示了如何使用gob包去创建二进制数据文件,以及如何去读取这些文件。
代码清单6-4 使用gob
包读写二进制数据
package main
import (
"bytes"
"encoding/gob"
"fmt"
"io/ioutil"
)
type Post struct {
Id int
Content string
Author string
}
func store(data interface{}, filename string) {// ①
buffer := new(bytes.Buffer)
encoder := gob.NewEncoder(buffer)
err := encoder.Encode(data)
if err != nil {
panic(err)
}
err = ioutil.WriteFile(filename, buffer.Bytes(), 0600)
if err != nil {
panic(err)
}
}
func load(data interface{}, filename string) {// ②
raw, err := ioutil.ReadFile(filename)
if err != nil {
panic(err)
}
buffer := bytes.NewBuffer(raw)
dec := gob.NewDecoder(buffer)
err = dec.Decode(data)
if err != nil {
panic(err)
}
}
func main() {
post := Post{Id: 1, Content: "Hello World!", Author: "Sau Sheong"}
store(post, "post1")
var postRead Post
load(&postRead, "post1")
fmt.Println(postRead)
}
① 存储数据② 载入数据
跟前面展示的程序一样,代码清单6-4所示的程序也会用到Post
结构,并且也包含了相应的store
方法和load
方法,但是跟之前不一样的是,这次的store
方法会将帖子存储为二进制数据,而load
方法则会通过读取这些二进制数据来获取帖子。
首先来分析一下store
函数,这个函数的第一个参数是一个空接口,而第二个参数则是被存储的二进制文件的名字。虽然空接口参数能够接受任意类型的数据作为值,但是在这个函数里面,它接受的将是一个Post
结构。在接受了相应的参数之后,store
函数会创建一个bytes.Buffer
结构,这个结构实际上就是一个拥有Read
方法和Write
方法的可变长度(variable sized)字节缓冲区,换句话说,bytes.Buffer
既是读取器也是写入器。
在此之后,store
函数会把缓冲区传递给NewEncoder
函数,以此来创建出一个gob
编码器,接着调用编码器的Encode
方法将数据(也就是Post
结构)编码到缓冲区里面,最后再将缓冲区中已编码的数据写入文件。
程序在调用store
函数时,会将一个Post
结构和一个文件名作为参数,而这个函数则会创建出一个名为post1
的二进制数据文件。
接下来,让我们来研究一下load
函数,这个函数从二进制数据文件中载入数据的步骤跟创建并写入这个文件的步骤正好相反:首先,程序会从文件里面读取出未经处理的原始数据;接着,程序会根据这些原始数据创建一个缓冲区,并藉此为原始数据提供相应的Read
方法和Write
方法;在此之后,程序会调用NewDecoder
函数,为缓冲区创建相应的解码器,然后使用解码器去解码从文件中读取的原始数据,并最终得到之前写入的Post
结构。
在main
函数里面,程序定义了一个名为postRead
的Post
结构,并将这个结构的引用以及二进制数据文件的名字传递给了load
函数,而load
函数则会把读取二进制文件所得的数据载入给定的Post
结构。
当我们运行代码清单6-4所示的程序时,将创建出一个包含二进制数据的post1
文件——因为这个文件包含的是二进制数据,所以如果直接打开这个文件,将会看到一些似乎毫无意义的数据。除创建post1
文件之外,程序还会读取文件中的数据并将其载入Post
结构里面,然后在控制终端打印出这个结构:
{1 Hello World! Sau Sheong}
好了,关于使用文件存储数据的介绍到此就结束了,本章接下来的内容将会讨论如何将数据存储到一种名为数据库服务器的特殊服务器端程序里面。