golang 包 encoding/binary
阿新 • • 發佈:2022-03-20
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)
連結:https://www.jianshu.com/p/ec461b39bf43 https://www.cnblogs.com/-wenli/p/12323809.html