Golang 读写二进制文件方法(二)

使用 Golang 的 encoding/gob 包读写二进制文件非常方便,而且代码量也非常少。但是在需要自定义二进制格式(自定义二进制格式有可能做到更紧凑的数据表示和更快的读写速度)的场景下,这个包就不适用了,这时候就需要使用到 encoding/binary 包了。

encoding/binary 包实现了数字(number)和字节序列(byte sequences)之间的简单转换以及 varints 的编码和解码,varints 是一种使用一个或多个字节表示整型数据的方法,其中数值本身越小,其所占用的字节数越少。

接下来演示一下序列化数据后保存到本地,再反序列化本地的数据。

序列化数据后保存到本地

package main

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"os"
)

type User struct {
	Age int32
}

funcmain() {
	file, err := os.Create("bin")
	if err != nil {
		fmt.Println("文件创建失败 ", err.Error())
		return
	}
	defer file.Close()

	for i := 1; i <= 10; i++ {
		data := User{
			int32(i),
		}
		var buf bytes.Buffer
		binary.Write(&buf, binary.LittleEndian, data)
		b := buf.Bytes()
		_, err = file.Write(b)
		if err != nil {
			fmt.Println("写入失败", err.Error())
			return
		}
	}
	fmt.Println("序列化成功")
}

反序列化本地的数据

package main

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"os"
)

type User struct {
	Age int32
}

funcmain() {
	file, err := os.Open("bin")
	if err != nil {
		fmt.Println("文件打开失败 ", err.Error())
		return
	}
	defer file.Close()

	data := User{}
	for i := 1; i <= 10; i++ {
		b := make([]byte, 4)
		_, err = file.Read(b)
		if err != nil {
			fmt.Println("反序列化失败", err)
		}
		buffer := bytes.NewBuffer(b)
		err = binary.Read(buffer, binary.LittleEndian, &data)
		if err != nil {
			fmt.Println("二进制文件读取失败", err)
			return
		}
		fmt.Println("第", i, "个值为:", data)
	}
}

更多关于 encoding/binary 的内容请参考此包的源代码。