1、golang包中的binary包是什么?
2、binary為我們開發者提供了哪些內容?以及怎么使用?
3、編解碼有哪幾種方法?
轉化成二進制格式與原本數據轉字符串相比會更節省空間
一、golang包中的binary包是什么?
此包實現了對數據與byte之間的轉換,以及varint的編解碼。
二、binary為我們開發者提供了哪些內容?以及怎么使用?
數據的byte序列化轉換
func Read(r io.Reader, order ByteOrder, data interface{}) error func Write(w io.Writer, order ByteOrder, data interface{}) error func Size(v interface{}) int
uvarint和varint的編解碼
func PutUvalint(buf []byte, x uint64) int func PutVarint(buf []byte, x int64) int func Uvarint(buf []byte) (uint64, int) func Varint(buf []byte) (int64, int) func ReadUvarint(r io.ByteReader) (uint64, error) func ReadVarint(r io.ByteReader) (int64, error)
結構體
type ByteOrder:可以定義自己的字節序結構,用於序列化和反序列化數據。
1)func Read(r io.Reader, order ByteOrder, data interface{}) error
參數列表:
1)r 可以讀出字節流的數據源 2)order 特殊字節序,包中提供大端字節序和小端字節序 3)data 需要解碼成的數據 返回值:error 返回錯誤 功能說明:Read從r中讀出字節數據並反序列化成結構數據。data必須是固定長的數據值或固定長數據的slice。從r中讀出的數據可以使用特殊的 字節序來解碼,並順序寫入value的字段。當填充結構體時,使用(_)名的字段講被跳過。
代碼案例
package main import ( "fmt" "log" "bytes" "encoding/binary" ) func main() { var pi float64 b := []byte{0x18,0x2d,0x44,0x54,0xfb,0x21,0x09,0x40} buf := bytes.NewBuffer(b) err := binary.Read(buf, binary.LittleEndian, &pi) if err != nil { log.Fatalln("binary.Read failed:", err) } fmt.Println(pi) }
2)Write(w io.Writer, order ByteOrder, data interface{}) error
參數列表:
1)w 可寫入字節流的數據 2)order 特殊字節序,包中提供大端字節序和小端字節序 3)data 需要解碼的數據 返回值:error 返回錯誤 功能說明: Write講data序列化成字節流寫入w中。data必須是固定長度的數據值或固定長數據的slice,或指向此類數據的指針。寫入w的字節流可用特殊的字節序來編碼。另外,結構體中的(_)名的字段講忽略。
代碼案例:
package main import ( "bytes" "math" "encoding/binary" "log" "fmt" ) func main() { buf := new(bytes.Buffer) pi := math.Pi err := binary.Write(buf, binary.LittleEndian, pi) if err != nil { log.Fatalln(err) } fmt.Println(buf.Bytes()) }
3)func Size(v interface{}) int
參數列表:v 需要計算長度的數據
返回值:int 數據序列化之后的字節長度 功能說明: Size講返回數據系列化之后的字節長度,數據必須是固定長數據類型、slice和結構體及其指針。
代碼實例
package main import ( "fmt" "encoding/binary" ) func main() { var a int p := &a b := [10]int64{1} s := "adsa" bs := make([]byte, 10) fmt.Println(binary.Size(a)) // -1 fmt.Println(binary.Size(p)) // -1 fmt.Println(binary.Size(b)) // 80 fmt.Println(binary.Size(s)) // -1 fmt.Println(binary.Size(bs)) // 10 }
4)func PutUvarint(buf []byte, x uint64) int
參數列表:
1)buf 需寫入的緩沖區 2)x uint64類型數字 返回值: 1)int 寫入字節數。 2)panic buf過小。 功能說明: PutUvarint主要是講uint64類型放入buf中,並返回寫入的字節數。如果buf過小,PutUvarint將拋出panic。
代碼案例
package main import ( "encoding/binary" "fmt" "strconv" ) func main() { u16 := 1234 u64 := 0x1020304040302010 sbuf := make([]byte, 4) buf := make([]byte, 10) ret := binary.PutUvarint(sbuf, uint64(u16)) fmt.Println(ret, len(strconv.Itoa(u16)), sbuf) ret = binary.PutUvarint(buf, uint64(u64)) fmt.Println(ret, len(strconv.Itoa(u64)), buf) } /* 輸出結果: 2 4 [210 9 0 0] 9 19 [144 192 192 129 132 136 140 144 16 0] 會發現轉成二進制來傳輸數據,比直接轉字符串之后轉[]byte這種方式傳更節省傳輸空間 */
5)func PutVarint(buf []byte, x int64) int
參數列表:
1)buf 需要寫入的緩沖區 2)x int64類型數字 返回值: 1)int 寫入字節數 2)panic buf過小 功能說明: PutVarint主要是講int64類型放入buf中,並返回寫入的字節數。如果buf過小,PutVarint將拋出panic。
代碼案例:
package main import ( "encoding/binary" "fmt" "strconv" ) func main() { i16 := 1234 i64 := -1234567890 sbuf := make([]byte, 4) buf := make([]byte, 10) ret := binary.PutVarint(buf, int64(i16)) fmt.Println(ret, len(strconv.Itoa(i16)), sbuf) ret = binary.PutVarint(buf, int64(i64)) fmt.Println(ret, len(strconv.Itoa(i64)), buf) } /* 2 4 [0 0 0 0] 5 11 [163 139 176 153 9 0 0 0 0 0] */
6)func Uvarint(buf []byte) (uint64, int)
參數列表:buf 需要解碼的緩沖區
返回值:
1)uint64 解碼的數據。 2)int 解析的字節數。 功能說明: Uvarint是從buf中解碼並返回一個uint64的數據,及解碼的字節數(>0)。如果出錯,則返回數據0和一個小於等於0的字節數n,其意義為: 1)n == 0: buf太小 2)n < 0: 數據太大,超出uint64最大范圍,且-n為已解析字節數
代碼案例
package main import ( "encoding/binary" "fmt" ) func main() { sbuf := []byte{} buf := []byte{144,192,192,132,136,140,144,16,0,1,1} bbuf := []byte{144,192,192,129,132,136,140,144,192,192,1,1} num, ret := binary.Uvarint(sbuf) fmt.Println(num, ret) num, ret = binary.Uvarint(buf) fmt.Println(num, ret) num, ret = binary.Uvarint(bbuf) fmt.Println(num, ret) }
- func Varint(buf []byte) (int64, int)
參數列表: buf 需要解碼的緩沖區 返回值: 1) int64 解碼的數據 2) int 解析的字節數 功能說明: Varint是從buf中解碼並返回一個int64的數據,及解碼的字節數(>0).如果出錯,則返回數據0和一個小於等於0的字節數n,其意義為: 1) n == 0: buf太小 2) n < 0: 數據太大,超出64位,且-n為已解析字節數
代碼案例
package main import ( "encoding/binary" "fmt" ) func main() { var sbuf []byte var buf []byte = []byte{144, 192, 192, 129, 132, 136, 140, 144, 16, 0, 1, 1} var bbuf []byte = []byte{144, 192, 192, 129, 132, 136, 140, 144, 192, 192, 1, 1} num, ret := binary.Varint(sbuf) fmt.Println(num, ret) //0 0 num, ret = binary.Varint(buf) fmt.Println(num, ret) //580990878187261960 9 num, ret = binary.Varint(bbuf) fmt.Println(num, ret) //0 -11 }
- func ReadUvarint(r io.ByteReader) (uint64, error)
參數列表: 返回值: 1) uint64 解析出的數據 2) error 返回的錯誤 功能說明: ReadUvarint從r中解析並返回一個uint64類型的數據及出現的錯誤. 功能說明: ReadUvarint從r中解析並返回一個uint64類型的數據及出現的錯誤.
代碼案例
package main import ( "bytes" "encoding/binary" "fmt" ) func main() { var sbuf []byte var buf []byte = []byte{144, 192, 192, 129, 132, 136, 140, 144, 16, 0, 1, 1} var bbuf []byte = []byte{144, 192, 192, 129, 132, 136, 140, 144, 192, 192, 1, 1} num, err := binary.ReadUvarint(bytes.NewBuffer(sbuf)) fmt.Println(num, err) //0 EOF num, err = binary.ReadUvarint(bytes.NewBuffer(buf)) fmt.Println(num, err) //1161981756374523920 <nil> num, err = binary.ReadUvarint(bytes.NewBuffer(bbuf)) fmt.Println(num, err) //4620746270195064848 binary: varint overflows a 64-bit integer }
- func ReadVarint(r io.ByteReader) (int64, error)
參數列表: r 實現ByteReader接口的對象 返回值: 1) int64 解析出的數據 2) error 返回的錯誤 功能說明: ReadVarint從r中解析並返回一個int64類型的數據及出現的錯誤.
代碼案例
package main import ( "bytes" "encoding/binary" "fmt" ) func main() { var sbuf []byte var buf []byte = []byte{144, 192, 192, 129, 132, 136, 140, 144, 16, 0, 1, 1} var bbuf []byte = []byte{144, 192, 192, 129, 132, 136, 140, 144, 192, 192, 1, 1} num, err := binary.ReadVarint(bytes.NewBuffer(sbuf)) fmt.Println(num, err) //0 EOF num, err = binary.ReadVarint(bytes.NewBuffer(buf)) fmt.Println(num, err) //580990878187261960 <nil> num, err = binary.ReadVarint(bytes.NewBuffer(bbuf)) fmt.Println(num, err) //2310373135097532424 binary: varint overflows a 64-bit integer }
三、編解碼有哪幾種方法?
編碼
- func Write(w io.Writer, order ByteOrder, data interface{}) error
- func PutUvarint(buf []byte, x uint64) int
- func PutVarint(buf []byte, x int64) int
解析
1)func Uvarint(buf []byte) (uint64, int)
2)func Varint(buf []byte) (int64, int)
3)func ReadUvarint(r io.ByteReader) (uint64, error)
4)func ReadVarint(r io.ByteReader) (int64, error)
作者:laijh
鏈接:https://www.jianshu.com/p/ec461b39bf43
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。