• golang中encoding/binary包


    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)
    }
    
    1. 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
    }
    
    1. 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
    }
    
    1. 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
    }
    

    三、编解码有哪几种方法?
    编码

    1. func Write(w io.Writer, order ByteOrder, data interface{}) error
    2. func PutUvarint(buf []byte, x uint64) int
    3. 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)

     
     
    5人点赞
     
     


    作者:laijh
    链接:https://www.jianshu.com/p/ec461b39bf43
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    我的第一个java程序
    ==和equals的区别
    后缀数组题目总结
    后缀数组入门
    【POJ.3415 Common Substrings】后缀数组 长度不小于K的公共子串个数
    【UOJ #519 查查查乐乐】 DP
    【CF-1350 D. Orac and Medians】 思维
    【CF-1350 C
    【CF 1350 B.Orac and Models】 DP
    【POJ-2774】Long Long Message 后缀数组 最长公共子串(出现两次不重叠子串)
  • 原文地址:https://www.cnblogs.com/sunlong88/p/13419708.html
Copyright © 2020-2023  润新知