18 Go的Gob

概述

在上一节的内容中,我们介绍了Go的文件操作,包括:读取文件、写入文件、删除文件、目录操作、遍历目录下文件等。在本节中,我们将介绍Go的Gob。Gob是Go语言中的一种序列化二进制格式,用于在Go语言之间进行数据传输和持久化存储,具有高效和紧凑的特点。Gob编码器将Go语言中的数据结构转换为二进制格式,而Gob解码器则将二进制格式的数据解码为Go语言中的数据结构。Gob使用可扩展的编码方案,可以处理任意类型的数据结构,包括:数组、切片、映射、嵌套结构等。

Gob简介

Gob是专门为Go语言设计,用于序列化和反序列化数据的一种格式,位于"encoding/gob"包中。

Gob的特点在于它是一种自描述的二进制格式,包含所有类型的描述,并且可以由Go语言解码,而无需了解文件的内容。只有可导出的字段会被编码,零值会被忽略。在解码结构体的时候,只有同时匹配名称和可兼容类型的字段才会被解码。当源数据类型增加新字段后,Gob解码仍然可以正常工作,解码客户端会继续识别以前存在的字段。

注意:Gob并不是一种不同于Go的语言,而是在编码和解码过程中用到了Go的反射。它是一种二进制格式,不像Json或XML那样是文本格式。

Gob编码

Gob编码器可以将Go语言中的数据结构转换为二进制格式,以便在网络传输或持久化存储时使用。下面是一些常用的编码函数。

NewEncoder(io.Writer) Encoder:创建一个新的编码器,用于将Go语言的数据结构编码为二进制格式。参数是一个io.Writer,编码的数据将写入该Writer中。

Encode(interface{}) error:使用指定的编码器将一个Go语言的数据结构编码为二进制格式,并写入指定的Writer中。参数是一个实现了interface{}类型的值,该函数将自动为该值编码。

GobEncode(interface{}) ([]byte, error):将一个Go语言的数据结构编码为Gob格式的字节切片,参数是一个实现了interface{}类型的值,该函数将自动为该值编码。

在下面的示例代码中,我们首先定义了一个Person结构体,它具有Name和Age两个字段。然后,我们创建了一个Person对象person。接下来,我们创建了一个文件person.gob,用于写入编码后的数据。最后,我们创建了一个编码器encoder,它将Person对象编码为Gob格式并写入文件。注意:Person结构体中的属性名必须为大写,否则编码时会出错,提示:"gob: type main.Person has no exported fields"。

Go 复制代码
package main

import "os"
import "fmt"
import "encoding/gob"

type Person struct {
    Name string
    Age  int
}

func main() {
    // 创建一个Person对象
    person := Person{"Mike", 18}

    // 创建文件,用于写入编码后的数据
    file, err := os.Create("person.gob")
    if err != nil {
        fmt.Println("Create failed:", err)
        return
    }

    defer file.Close()

    // 创建编码器,将Person对象编码为GOB格式并写入文件
    encoder := gob.NewEncoder(file)
    err = encoder.Encode(person)
    if err != nil {
        fmt.Println("Encode failed:", err)
        return
    }

    fmt.Println("Encode success")
}

Gob解码

Gob解码器可以将二进制格式的数据解码为Go语言中的数据结构,下面是一些常用的解码函数。

NewDecoder(io.Reader) Decoder:创建一个新的解码器,用于从二进制格式的数据中解码出Go语言的数据结构。参数是一个io.Reader,解码的数据将从该Reader中读取。

Decode(interface{}) error:使用指定的解码器从二进制格式的数据中解码出一个Go语言的数据结构,并存储在指定的值中。参数是一个实现了interface{}类型的值,该函数将自动为该值解码。

GobDecode([]byte, interface{}) error:从一个Gob格式的字节切片中解码出一个Go语言的数据结构,并存储在指定的值中。参数是一个实现了interface{}类型的值,该函数将自动为该值解码。

在下面的示例代码中,我们首先定义了一个Person结构体,它具有Name和Age两个字段。接下来,我们读取了上述编码好的文件person.gob,用于从文件中解码数据。最后,我们创建了一个解码器decoder,用于从文件中读取Gob格式的数据,并解码存入到person对象中。

Go 复制代码
package main

import "os"
import "fmt"
import "encoding/gob"

type Person struct {
    Name string
    Age  int
}

func main() {
    person := Person{}

     // 创建一个文件用于写入编码后的数据
     file, err := os.Open("person.gob")
     if err != nil {
         fmt.Println("Open failed:", err)
         return
     }

     defer file.Close()

     // 创建解码器,从文件中解码GOB格式数据并存入Person对象
     decoder := gob.NewDecoder(file)
     err = decoder.Decode(&person)
     if err != nil {
         fmt.Println("Decode failed:", err)
         return
     }

     // 输出:Decode success: {Mike 18}
     fmt.Println("Decode success:", person)
}

除了可以将数据结构编码到文件中,还可以将数据结构编码到字节切片中,并从字节切片中解码。

在下面的示例代码中,我们首先定义了一个Person结构体。然后,我们创建了一个缓冲区buf,用于存储编码后的数据。接下来,我们创建了一个编码器encoder,它将数据person编码为gob格式并写入缓冲区buf。最后,我们创建了一个解码器decoder,它从缓冲区中读取编码后的数据并解码为Person对象decodedPerson。

Go 复制代码
package main

import "fmt"
import "bytes"
import "encoding/gob"

type Person struct {
    Name string
    Age  int
}
  
func main() {
    // 创建一个缓冲区,用于编码数据
    var buf bytes.Buffer
    // 创建一个编码器,将数据编码为gob格式并写入缓冲区
    encoder := gob.NewEncoder(&buf)
    // 创建一个Person对象
    person := Person{"Mike", 18}

    // 将Person对象编码为gob格式并写入缓冲区
    err := encoder.Encode(person)
    if err != nil {
        fmt.Println("Encode failed:", err)
        return
    }

    // 从缓冲区中读取编码后的数据
    decodedPerson := Person{}
    decoder := gob.NewDecoder(&buf)
    err = decoder.Decode(&decodedPerson)
    if err != nil {
        fmt.Println("Decode failed:", err)
        return
    }

    // 输出:Decoded data: {Mike 18}
    fmt.Println("Decoded data:", decodedPerson)
}
相关推荐
qq_172805594 小时前
GO GIN 推荐的库
开发语言·golang·gin
=(^.^)=哈哈哈5 小时前
Golang如何优雅的退出程序
开发语言·golang·xcode
白总Server10 小时前
MongoDB解说
开发语言·数据库·后端·mongodb·golang·rust·php
liupenglove14 小时前
golang操作mysql利器-gorm
mysql·golang
Rookie_explorers15 小时前
Linux下go环境安装、环境配置并执行第一个go程序
linux·运维·golang
做技术的Pandaer15 小时前
Go 第二期
开发语言·golang
wn53116 小时前
【Go - 类型断言】
服务器·开发语言·后端·golang
GoppViper17 小时前
golang学习笔记29——golang 中如何将 GitHub 最新提交的版本设置为 v1.0.0
笔记·git·后端·学习·golang·github·源代码管理
_小许_1 天前
Go语言的io输入输出流
golang
白总Server1 天前
MySQL在大数据场景应用
大数据·开发语言·数据库·后端·mysql·golang·php