最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Golang使用gob實(shí)現(xiàn)結(jié)構(gòu)體的序列化過程詳解

 更新時(shí)間:2023年03月08日 08:30:04   作者:夢(mèng)想畫家  
Golang struct類型數(shù)據(jù)序列化用于網(wǎng)絡(luò)傳輸數(shù)據(jù)或在磁盤上寫入數(shù)據(jù)。在分布式系統(tǒng)中,一端生成數(shù)據(jù)、然后序列化、壓縮和發(fā)送;在另一端,接收數(shù)據(jù)、然后解壓縮、反序列化和處理數(shù)據(jù),整個(gè)過程必須快速有效

Golang有自己的序列化格式,稱為gob。使用gob可以對(duì)結(jié)構(gòu)進(jìn)行編碼和解碼。你可以使用其他格式,如JSON, XML, protobuff等,具體選擇要根據(jù)實(shí)際需求,但當(dāng)接收和發(fā)送都為Golang,我建議使用Go的gob格式。

Gob簡介

gob在kg/encoding/gob包中:

  • gob流是自描述的,這意味著我們不需要?jiǎng)?chuàng)建單獨(dú)的文件來解釋(使用protobuff格式需要?jiǎng)?chuàng)建文件)
  • gob流中的每個(gè)數(shù)據(jù)項(xiàng)之前都有其類型說明(一些預(yù)定義的類型)

Gob包很簡單,僅包括8個(gè)函數(shù)和5個(gè)類型:

func Register(value interface{})
func RegisterName(name string, value interface{})
type CommonType
type Decoder
func NewDecoder(r io.Reader) *Decoder
func (dec *Decoder) Decode(e interface{}) error
func (dec *Decoder) DecodeValue(v reflect.Value) error
type Encoder
func NewEncoder(w io.Writer) *Encoder
func (enc *Encoder) Encode(e interface{}) error
func (enc *Encoder) EncodeValue(value reflect.Value) error
type GobDecoder
type GobEncoder

單個(gè)對(duì)象序列化

首先定義student結(jié)構(gòu)體,包括兩個(gè)字段Name和Age.

使用gob.NewEncoder和gob.NewDecoder方法,接收io.Writer 和 io.Reader 對(duì)象,用于讀寫文件:

package main
import (
       "fmt"
       "os"
       "encoding/gob"
)
type Student struct {
       Name string
       Age int32
}
func main() {
       fmt.Println("Gob Example")
       student := Student{"Ketan Parmar",35}
       err := writeGob("./student.gob",student)
       if err != nil{
              fmt.Println(err)
       }
       var studentRead = new (Student)
       err = readGob("./student.gob",studentRead)
       if err != nil {
              fmt.Println(err)
       } else {
              fmt.Println(studentRead.Name, "\t", studentRead.Age)
       }
}
func writeGob(filePath string,object interface{}) error {
       file, err := os.Create(filePath)
       if err == nil {
              encoder := gob.NewEncoder(file)
              encoder.Encode(object)
       }
       file.Close()
       return err
}
func readGob(filePath string,object interface{}) error {
       file, err := os.Open(filePath)
       if err == nil {
              decoder := gob.NewDecoder(file)
              err = decoder.Decode(object)
       }
       file.Close()
       return err
}

列表數(shù)據(jù)序列化

首先創(chuàng)建student結(jié)構(gòu)體數(shù)組或slice,然后填充數(shù)據(jù)。下面示例無需修改readGob和writeGob函數(shù):

package main
import (
       "fmt"
       "os"
       "encoding/gob"
)
type Student struct {
       Name string
       Age int32
}
type Students []Student
func main() {
       fmt.Println("Gob Example")
       students := Students{}
       students = append(students,Student{"Student 1",20})
       students = append(students,Student{"Student 2",25})
       students = append(students,Student{"Student 3",30})
       err := writeGob("./student.gob",students)
       if err != nil{
              fmt.Println(err)
       }
       var studentRead = new (Students)
       err = readGob("./student.gob",studentRead)
       if err != nil {
              fmt.Println(err)
       } else {
              for _,v := range *studentRead{
                     fmt.Println(v.Name, "\t", v.Age)
              }
       }
}

上面兩個(gè)示例主要使用了NewEncoder 和 NewDecoder,接下來看看其他函數(shù):Register, Encode, EncodeValue, Decode 和 DecodeValue。

Encode 和 Decode 函數(shù)主要用于網(wǎng)絡(luò)應(yīng)用程序,方法簽名如下:

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

簡單編碼示例

package main
import (
   "fmt"
   "encoding/gob"
   "bytes"
)
type Student struct {
   Name string
   Age int32
}
func main() {
   fmt.Println("Gob Example")
   studentEncode := Student{Name:"Ketan",Age:30}
   var b bytes.Buffer
   e := gob.NewEncoder(&b)
   if err := e.Encode(studentEncode); err != nil {
      panic(err)
   }
   fmt.Println("Encoded Struct ", b)
   var studentDecode Student
   d := gob.NewDecoder(&b)
   if err := d.Decode(&studentDecode); err != nil {
      panic(err)
   }
   fmt.Println("Decoded Struct ", studentDecode.Name,"\t",studentDecode.Age)
}

上面示例把student結(jié)構(gòu)序列化、反序列化。序列化后存儲(chǔ)在字節(jié)buffer變量b中,先可以使用b在網(wǎng)絡(luò)中傳輸。要解碼僅需要?jiǎng)?chuàng)建相同結(jié)構(gòu)對(duì)象并提供其地址。studentDecode變量獲得解碼的內(nèi)容。

編碼在TCP連接中使用

TCP客戶端:打開連接使用gob.Encoder方法編碼數(shù)據(jù)進(jìn)行傳輸:

package main
import (
   "fmt"
   "encoding/gob"
   "net"
   "log"
)
type Student struct {
   Name string
   Age int32
}
func main() {
   fmt.Println("Client")
   //create structure object
    studentEncode := Student{Name:"Ketan",Age:30}
   fmt.Println("start client");
   // dial TCP connection
   conn, err := net.Dial("tcp", "localhost:8080")
   if err != nil {
      log.Fatal("Connection error", err)
   }
   //Create encoder object, We are passing connection object in Encoder
   encoder := gob.NewEncoder(conn)
   // Encode Structure, IT will pass student object over TCP connection
   encoder.Encode(studentEncode)
   // close connection
   conn.Close()
   fmt.Println("done");
}

TCP Server: 監(jiān)聽8080端口,在go協(xié)程中處理所有客戶端,使用gob.Decoder方法解碼student結(jié)構(gòu)體并輸出:

package main
import (
   "fmt"
   "net"
   "encoding/gob"
)
type Student struct {
   Name string
   Age int32
}
func handleConnection(conn net.Conn) {
   // create new decoder object and provide connection
   dec := gob.NewDecoder(conn)
   // create blank student object
   p := &Student{}
   // decode serialize data
   dec.Decode(p)
   // print
   fmt.Println("Hello ",p.Name,", Your Age is ",p.Age);
   // close connection for that client
   conn.Close()
}
func main() {
   fmt.Println("Server")
   // start TCP server and listen on port 8080
   ln, err := net.Listen("tcp", ":8080")
   if err != nil {
      // handle error
      panic(err)
   }
   for {
      // this blocks until connection or error
      conn, err := ln.Accept()
      if err != nil {
         // handle error
         continue
      }
      // a goroutine handles conn so that the loop can accept other connections
      go handleConnection(conn)
   }
}

上文中沒有實(shí)現(xiàn)序列化,本文給出golang-ttl-map實(shí)現(xiàn):

func (h *Heap) append(data Data) (err error) {
	h.fileMx.Lock()
	defer h.fileMx.Unlock()
       // 打開文件
	var file *os.File
	file, err = os.OpenFile(h.filePath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0755)
	if err != nil {
		return
	}
	defer func() {
		_ = file.Sync()
	}()
	defer func() {
		_ = file.Close()
	}()
       // 定義buffer
	var buf bytes.Buffer
	enc := gob.NewEncoder(&buf)
       // 序列化
	err = enc.Encode(data)
	if err != nil {
		return
	}
	bs := buf.Bytes()
	bs = append(bs, '\n')
       // 寫入文件
	_, err = file.Write(bs)
	if err != nil {
		return
	}
	return
}

到此這篇關(guān)于Golang使用gob實(shí)現(xiàn)結(jié)構(gòu)體的序列化過程詳解的文章就介紹到這了,更多相關(guān)Golang結(jié)構(gòu)體序列化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go語言HTTP服務(wù)實(shí)現(xiàn)GET和POST請(qǐng)求的同時(shí)支持

    Go語言HTTP服務(wù)實(shí)現(xiàn)GET和POST請(qǐng)求的同時(shí)支持

    做第三方接口有時(shí)需要用Get或者Post請(qǐng)求訪問,本文主要介紹了Golang發(fā)送Get和Post請(qǐng)求的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-05-05
  • Golang實(shí)現(xiàn)簡易的命令行功能

    Golang實(shí)現(xiàn)簡易的命令行功能

    這篇文章主要為大家詳細(xì)介紹了如何通過Golang實(shí)現(xiàn)一個(gè)簡易的命令行功能,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的可以了解一下
    2023-02-02
  • Golang使用channel實(shí)現(xiàn)一個(gè)優(yōu)雅退出功能

    Golang使用channel實(shí)現(xiàn)一個(gè)優(yōu)雅退出功能

    最近補(bǔ)?Golang?channel?方面八股的時(shí)候發(fā)現(xiàn)用?channel?實(shí)現(xiàn)一個(gè)優(yōu)雅退出功能好像不是很難,之前寫的?HTTP?框架剛好也不支持優(yōu)雅退出功能,于是就參考了?Hertz?優(yōu)雅退出方面的代碼,為我的?PIANO?補(bǔ)足了這個(gè)?feature
    2023-03-03
  • 基于微服務(wù)框架go-micro開發(fā)gRPC應(yīng)用程序

    基于微服務(wù)框架go-micro開發(fā)gRPC應(yīng)用程序

    這篇文章介紹了基于微服務(wù)框架go-micro開發(fā)gRPC應(yīng)用程序的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07
  • Go與C語言的互操作實(shí)現(xiàn)

    Go與C語言的互操作實(shí)現(xiàn)

    在Go與C語言互操作方面,Go更是提供了強(qiáng)大的支持。尤其是在Go中使用C,你甚至可以直接在Go源文件中編寫C代碼,本文就詳細(xì)的介紹一下如何使用,感興趣的可以了解一下
    2021-12-12
  • golang 如何獲取pem格式RSA公私鑰長度

    golang 如何獲取pem格式RSA公私鑰長度

    這篇文章主要介紹了golang 如何獲取pem格式RSA公私鑰長度操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • 如何使用騰訊云go sdk 查詢對(duì)象存儲(chǔ)中最新文件

    如何使用騰訊云go sdk 查詢對(duì)象存儲(chǔ)中最新文件

    這篇文章主要介紹了使用騰訊云go sdk 查詢對(duì)象存儲(chǔ)中最新文件,這包括如何創(chuàng)建COS客戶端,如何逐頁檢索對(duì)象列表,并如何對(duì)結(jié)果排序以找到最后更新的對(duì)象,我們還展示了如何優(yōu)化用戶體驗(yàn),通過實(shí)時(shí)進(jìn)度更新和檢索多個(gè)文件來改進(jìn)程序,需要的朋友可以參考下
    2024-03-03
  • go語言里包的用法實(shí)例

    go語言里包的用法實(shí)例

    這篇文章主要介紹了go語言里包的用法,實(shí)例分析了Go語言里包的原理與使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-02-02
  • Golang實(shí)現(xiàn)Biginteger大數(shù)計(jì)算實(shí)例詳解

    Golang實(shí)現(xiàn)Biginteger大數(shù)計(jì)算實(shí)例詳解

    這篇文章主要為大家介紹了Golang實(shí)現(xiàn)Biginteger大數(shù)計(jì)算實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • Go語言中iota的具體使用

    Go語言中iota的具體使用

    Go語言中,iota是一個(gè)用于生成一系列相關(guān)常量值的常量生成器,常應(yīng)用于枚舉、位操作等場(chǎng)景,廣泛用于定義HTTP狀態(tài)碼、權(quán)限控制等,本文就來介紹一下iota的具體使用,感興趣的可以了解一下
    2024-11-11

最新評(píng)論

子长县| 博客| 东乡县| 常州市| 龙游县| 德江县| 大埔区| 大埔区| 都昌县| 迭部县| 陆丰市| 东至县| 台北市| 德格县| 五莲县| 特克斯县| 新昌县| 牟定县| 巴彦县| 澄城县| 乌拉特后旗| 易门县| 海原县| 邯郸市| 永定县| 清河县| 肥西县| 岑巩县| 富源县| 淄博市| 会宁县| 微博| 屯留县| 广灵县| 双辽市| 抚顺市| 宝丰县| 高台县| 二连浩特市| 宜昌市| 封丘县|