Golang怎么使用gob实现结构体的序列化

其他教程   发布日期:2023年08月02日   浏览次数:410

本文小编为大家详细介绍“Golang怎么使用gob实现结构体的序列化”,内容详细,步骤清晰,细节处理妥当,希望这篇“Golang怎么使用gob实现结构体的序列化”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

Golang有自己的序列化格式,称为gob。使用gob可以对结构进行编码和解码。你可以使用其他格式,如JSON, XML, protobuff等,具体选择要根据实际需求,但当接收和发送都为Golang,我建议使用Go的gob格式。

Gob简介

gob在kg/encoding/gob包中:

  • gob流是自描述的,这意味着我们不需要创建单独的文件来解释(使用protobuff格式需要创建文件)

  • gob流中的每个数据项之前都有其类型说明(一些预定义的类型)

Gob包很简单,仅包括8个函数和5个类型:

  1. func Register(value interface{})
  2. func RegisterName(name string, value interface{})
  3. type CommonType
  4. type Decoder
  5. func NewDecoder(r io.Reader) *Decoder
  6. func (dec *Decoder) Decode(e interface{}) error
  7. func (dec *Decoder) DecodeValue(v reflect.Value) error
  8. type Encoder
  9. func NewEncoder(w io.Writer) *Encoder
  10. func (enc *Encoder) Encode(e interface{}) error
  11. func (enc *Encoder) EncodeValue(value reflect.Value) error
  12. type GobDecoder
  13. type GobEncoder

单个对象序列化

首先定义student结构体,包括两个字段Name和Age.

使用gob.NewEncoder和gob.NewDecoder方法,接收io.Writer 和 io.Reader 对象,用于读写文件:

  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "encoding/gob"
  6. )
  7. type Student struct {
  8. Name string
  9. Age int32
  10. }
  11. func main() {
  12. fmt.Println("Gob Example")
  13. student := Student{"Ketan Parmar",35}
  14. err := writeGob("./student.gob",student)
  15. if err != nil{
  16. fmt.Println(err)
  17. }
  18. var studentRead = new (Student)
  19. err = readGob("./student.gob",studentRead)
  20. if err != nil {
  21. fmt.Println(err)
  22. } else {
  23. fmt.Println(studentRead.Name, " ", studentRead.Age)
  24. }
  25. }
  26. func writeGob(filePath string,object interface{}) error {
  27. file, err := os.Create(filePath)
  28. if err == nil {
  29. encoder := gob.NewEncoder(file)
  30. encoder.Encode(object)
  31. }
  32. file.Close()
  33. return err
  34. }
  35. func readGob(filePath string,object interface{}) error {
  36. file, err := os.Open(filePath)
  37. if err == nil {
  38. decoder := gob.NewDecoder(file)
  39. err = decoder.Decode(object)
  40. }
  41. file.Close()
  42. return err
  43. }

列表数据序列化

首先创建student结构体数组或slice,然后填充数据。下面示例无需修改readGob和writeGob函数:

  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "encoding/gob"
  6. )
  7. type Student struct {
  8. Name string
  9. Age int32
  10. }
  11. type Students []Student
  12. func main() {
  13. fmt.Println("Gob Example")
  14. students := Students{}
  15. students = append(students,Student{"Student 1",20})
  16. students = append(students,Student{"Student 2",25})
  17. students = append(students,Student{"Student 3",30})
  18. err := writeGob("./student.gob",students)
  19. if err != nil{
  20. fmt.Println(err)
  21. }
  22. var studentRead = new (Students)
  23. err = readGob("./student.gob",studentRead)
  24. if err != nil {
  25. fmt.Println(err)
  26. } else {
  27. for _,v := range *studentRead{
  28. fmt.Println(v.Name, " ", v.Age)
  29. }
  30. }
  31. }

上面两个示例主要使用了NewEncoder 和 NewDecoder,接下来看看其他函数:Register, Encode, EncodeValue, Decode 和 DecodeValue。

Encode 和 Decode 函数主要用于网络应用程序,方法签名如下:

func (dec *Decoder) Decode(e interface{}) error
func (enc *Encoder) Encode(e interface{}) error

简单编码示例

  1. package main
  2. import (
  3. "fmt"
  4. "encoding/gob"
  5. "bytes"
  6. )
  7. type Student struct {
  8. Name string
  9. Age int32
  10. }
  11. func main() {
  12. fmt.Println("Gob Example")
  13. studentEncode := Student{Name:"Ketan",Age:30}
  14. var b bytes.Buffer
  15. e := gob.NewEncoder(&b)
  16. if err := e.Encode(studentEncode); err != nil {
  17. panic(err)
  18. }
  19. fmt.Println("Encoded Struct ", b)
  20. var studentDecode Student
  21. d := gob.NewDecoder(&b)
  22. if err := d.Decode(&studentDecode); err != nil {
  23. panic(err)
  24. }
  25. fmt.Println("Decoded Struct ", studentDecode.Name," ",studentDecode.Age)
  26. }

上面示例把student结构序列化、反序列化。序列化后存储在字节buffer变量b中,先可以使用b在网络中传输。要解码仅需要创建相同结构对象并提供其地址。studentDecode变量获得解码的内容。

编码在TCP连接中使用

TCP客户端:打开连接使用gob.Encoder方法编码数据进行传输:

  1. package main
  2. import (
  3. "fmt"
  4. "encoding/gob"
  5. "net"
  6. "log"
  7. )
  8. type Student struct {
  9. Name string
  10. Age int32
  11. }
  12. func main() {
  13. fmt.Println("Client")
  14. //create structure object
  15. studentEncode := Student{Name:"Ketan",Age:30}
  16. fmt.Println("start client");
  17. // dial TCP connection
  18. conn, err := net.Dial("tcp", "localhost:8080")
  19. if err != nil {
  20. log.Fatal("Connection error", err)
  21. }
  22. //Create encoder object, We are passing connection object in Encoder
  23. encoder := gob.NewEncoder(conn)
  24. // Encode Structure, IT will pass student object over TCP connection
  25. encoder.Encode(studentEncode)
  26. // close connection
  27. conn.Close()
  28. fmt.Println("done");
  29. }

TCP Server: 监听8080端口,在go协程中处理所有客户端,使用gob.Decoder方法解码student结构体并输出:

  1. package main
  2. import (
  3. "fmt"
  4. "net"
  5. "encoding/gob"
  6. )
  7. type Student struct {
  8. Name string
  9. Age int32
  10. }
  11. func handleConnection(conn net.Conn) {
  12. // create new decoder object and provide connection
  13. dec := gob.NewDecoder(conn)
  14. // create blank student object
  15. p := &Student{}
  16. // decode serialize data
  17. dec.Decode(p)
  18. // print
  19. fmt.Println("Hello ",p.Name,", Your Age is ",p.Age);
  20. // close connection for that client
  21. conn.Close()
  22. }
  23. func main() {
  24. fmt.Println("Server")
  25. // start TCP server and listen on port 8080
  26. ln, err := net.Listen("tcp", ":8080")
  27. if err != nil {
  28. // handle error
  29. panic(err)
  30. }
  31. for {
  32. // this blocks until connection or error
  33. conn, err := ln.Accept()
  34. if err != nil {
  35. // handle error
  36. continue
  37. }
  38. // a goroutine handles conn so that the loop can accept other connections
  39. go handleConnection(conn)
  40. }
  41. }

上文中没有实现序列化,本文给出golang-ttl-map实现:

  1. func (h *Heap) append(data Data) (err error) {
  2. h.fileMx.Lock()
  3. defer h.fileMx.Unlock()
  4. // 打开文件
  5. var file *os.File
  6. file, err = os.OpenFile(h.filePath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0755)
  7. if err != nil {
  8. return
  9. }
  10. defer func() {
  11. _ = file.Sync()
  12. }()
  13. defer func() {
  14. _ = file.Close()
  15. }()
  16. // 定义buffer
  17. var buf bytes.Buffer
  18. enc := gob.NewEncoder(&buf)
  19. // 序列化
  20. err = enc.Encode(data)
  21. if err != nil {
  22. return
  23. }
  24. bs := buf.Bytes()
  25. bs = append(bs, '
  26. ')
  27. // 写入文件
  28. _, err = file.Write(bs)
  29. if err != nil {
  30. return
  31. }
  32. return
  33. }

以上就是Golang怎么使用gob实现结构体的序列化的详细内容,更多关于Golang怎么使用gob实现结构体的序列化的资料请关注九品源码其它相关文章!