沙滩星空的博客沙滩星空的博客

Go语言对二进制文件的读写操作

Gob数据格式

为了让某个数据结构能够在网络上传输或保存至文件,它必须被 编码解码 。当然已经有许多可用的编码方式了,比如 JSONXML、Google 的 protocol buffers 等等。而现在又多了一种,由Go语言 encoding/gob 包提供的方式。

Gob 是Go语言自己以 二进制 形式序列化和反序列化程序数据的格式,可以在 encoding 包中找到。这种格式的数据简称为 Gob(即 Go binary 的缩写)。类似于 Python 的“pickle”和 Java 的“Serialization”。

虽然 JSON 的序列化更为通用,但利用 Gob 编码可以实现 JSON 所不能支持的 struct 的 方法序列化,利用 Gob 包序列化 struct 保存到本地也十分简单。

  • 创建 gob 文件
package main
import (
    "encoding/gob"
    "fmt"
    "os"
)
func main() {
    info := map[string]string{
        "name":    "C语言中文网",
        "website": "http://c.biancheng.net/golang/",
    }
    name := "demo.gob"
    File, _ := os.OpenFile(name, os.O_RDWR|os.O_CREATE, 0777)
    defer File.Close()
    enc := gob.NewEncoder(File)
    if err := enc.Encode(info); err != nil {
        fmt.Println(err)
    }
}
  • 读取 gob 文件
package main
import (
    "encoding/gob"
    "fmt"
    "os"
)
func main() {
    var M map[string]string
    File, _ := os.Open("demo.gob")
    D := gob.NewDecoder(File)
    D.Decode(&M)
    fmt.Println(M)
}

自定义二进制数据格式

  • 写自定义二进制文件

Go语言的 encoding/binary 包中的 binary.Write() 函数使得以二进制格式写数据非常简单,函数原型如下:

func Write(w io.Writer, order ByteOrder, data interface{}) error
package main
import (
    "bytes"
    "encoding/binary"
    "fmt"
    "os"
)
type Website struct {
    Url int32
}
func main() {
    file, err := os.Create("output.bin")
    for i := 1; i <= 10; i++ {
        info := Website{
            int32(i),
        }
        if err != nil {
            fmt.Println("文件创建失败 ", err.Error())
            return
        }
        defer file.Close()
        var bin_buf bytes.Buffer
        binary.Write(&bin_buf, binary.LittleEndian, info)
        b := bin_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 Website struct {
    Url int32
}
func main() {
    file, err := os.Open("output.bin")
    defer file.Close()
    if err != nil {
        fmt.Println("文件打开失败", err.Error())
        return
    }
    m := Website{}
    for i := 1; i <= 10; i++ {
        data := readNextBytes(file, 4)
        buffer := bytes.NewBuffer(data)
        err = binary.Read(buffer, binary.LittleEndian, &m)
        if err != nil {
            fmt.Println("二进制文件读取失败", err)
            return
        }
        fmt.Println("第", i, "个值为:", m)
    }
}
func readNextBytes(file *os.File, number int) []byte {
    bytes := make([]byte, number)
    _, err := file.Read(bytes)
    if err != nil {
        fmt.Println("解码失败", err)
    }
    return bytes
}

Go语言使用Gob传输数据 https://c.biancheng.net/view/4597.html
Go语言自定义二进制文件的读写操作 https://c.biancheng.net/view/4570.html

未经允许不得转载:沙滩星空的博客 » Go语言对二进制文件的读写操作

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址