Golang如何操作二進制數據 Golang字節處理指南

golang的encoding/binary包配合切片可用于高效處理二進制數據。1. 使用binary.bigendian或binary.littleendian實現字節序轉換,通過binary.write和binary.read指定字節序進行寫入與讀取;2. 處理變長數據時,先寫入/讀取長度字段,再操作實際數據;3. 用Struct定義二進制結構時,結合固定大小的byte數組和binary.littleendian或binary.bigendian完成數據序列化與反序列化,并注意對字符串截斷處理空字節。

Golang如何操作二進制數據 Golang字節處理指南

操作二進制數據,說白了,就是在字節層面“玩耍”。golang提供了強大的encoding/binary包,再加上切片(slice)的靈活運用,讓你能夠自如地讀取、寫入、轉換各種二進制格式的數據。掌握它,你就打開了處理網絡協議、圖像文件、壓縮數據等等的大門。

Golang如何操作二進制數據 Golang字節處理指南

encoding/binary包 + 切片

Golang如何操作二進制數據 Golang字節處理指南

如何使用encoding/binary進行字節序轉換?

字節序,也就是字節的排列順序,分為大端(Big Endian)和小端(Little Endian)。不同的系統或協議可能采用不同的字節序。encoding/binary包提供了BigEndian和LittleEndian兩個類型,分別代表大端和小端。

立即學習go語言免費學習筆記(深入)”;

Golang如何操作二進制數據 Golang字節處理指南

package main  import (     "bytes"     "encoding/binary"     "fmt" )  func main() {     var num int32 = 12345 // 示例數據      // 大端字節序     bufBig := new(bytes.Buffer)     err := binary.Write(bufBig, binary.BigEndian, num)     if err != nil {         fmt.Println("binary.Write failed:", err)         return     }     fmt.Printf("Big Endian: %Xn", bufBig.Bytes())      // 小端字節序     bufLittle := new(bytes.Buffer)     err = binary.Write(bufLittle, binary.LittleEndian, num)     if err != nil {         fmt.Println("binary.Write failed:", err)         return     }     fmt.Printf("Little Endian: %Xn", bufLittle.Bytes())      // 從字節數組讀取數據,并指定字節序     var readNum int32     reader := bytes.NewReader(bufLittle.Bytes())     err = binary.Read(reader, binary.LittleEndian, &readNum)     if err != nil {         fmt.Println("binary.Read failed:", err)         return     }     fmt.Printf("Read Number: %dn", readNum) }

這個例子展示了如何將一個int32類型的數字,分別以大端和小端字節序寫入bytes.Buffer,并演示了如何從小端字節序的bytes.Buffer中讀取數據。注意,binary.Write和binary.Read的第二個參數就是用來指定字節序的。

如何處理變長二進制數據?

有時候,二進制數據的長度不是固定的,比如網絡協議中,經常會用一個字段來表示后續數據的長度。這時,就需要先讀取長度字段,再根據長度讀取實際數據。

package main  import (     "bytes"     "encoding/binary"     "fmt" )  func main() {     // 模擬一段變長數據,長度為10,數據為 "abcdefghij"     data := []byte("abcdefghij")     length := int32(len(data))      // 創建一個buffer,先寫入長度,再寫入數據     buf := new(bytes.Buffer)     err := binary.Write(buf, binary.BigEndian, length) // 先寫入長度     if err != nil {         fmt.Println("binary.Write length failed:", err)         return     }     _, err = buf.Write(data) // 再寫入數據     if err != nil {         fmt.Println("buf.Write data failed:", err)         return     }      // 從buffer中讀取數據     readBuf := bytes.NewReader(buf.Bytes())     var readLength int32     err = binary.Read(readBuf, binary.BigEndian, &readLength) // 先讀取長度     if err != nil {         fmt.Println("binary.Read length failed:", err)         return     }      readData := make([]byte, readLength)     _, err = readBuf.Read(readData) // 再讀取數據     if err != nil {         fmt.Println("readBuf.Read data failed:", err)         return     }      fmt.Printf("Read Length: %dn", readLength)     fmt.Printf("Read Data: %sn", String(readData)) }

這段代碼模擬了變長數據的寫入和讀取。關鍵在于先讀取長度字段,然后根據長度字段創建切片,再讀取實際數據。

如何使用struct來定義二進制數據結構

Golang的struct非常適合用來定義二進制數據結構。通過在struct字段上使用binary tag,可以指定字段的字節序和偏移量。

package main  import (     "bytes"     "encoding/binary"     "fmt" )  // 定義一個結構體,模擬二進制數據結構 type MyData struct {     ID   int32  // ID     Name [16]byte // Name, 固定長度16字節     Value float64 // Value }  func main() {     // 創建一個MyData實例     myData := MyData{         ID:    123,         Name:  [16]byte{'G', 'o', 'l', 'a', 'n', 'g'}, // 初始化部分Name         Value: 3.1415926,     }      // 將結構體寫入buffer     buf := new(bytes.Buffer)     err := binary.Write(buf, binary.LittleEndian, &myData)     if err != nil {         fmt.Println("binary.Write failed:", err)         return     }      // 從buffer中讀取數據,并填充到結構體     readBuf := bytes.NewReader(buf.Bytes())     var readData MyData     err = binary.Read(readBuf, binary.LittleEndian, &readData)     if err != nil {         fmt.Println("binary.Read failed:", err)         return     }      // 打印讀取到的數據     fmt.Printf("ID: %dn", readData.ID)     fmt.Printf("Name: %sn", string(readData.Name[:])) // 注意截斷,去掉多余的空字節     fmt.Printf("Value: %fn", readData.Value) }

在這個例子中,MyData結構體定義了一個包含ID、Name和Value字段的二進制數據結構。使用binary.Write和binary.Read可以直接將結構體寫入和讀取到bytes.Buffer。注意,對于固定長度的字符串,需要使用[N]byte數組,而不是string類型。另外,讀取Name字段時,需要進行截斷,去掉多余的空字節。

? 版權聲明
THE END
喜歡就支持一下吧
點贊15 分享