©
This document uses PHP Chinese website manual Release
import "encoding/binary"
Overview
Index
Examples
软件包二进制实现了数字和字节序列之间的简单转换以及varint的编码和解码。
数字通过读取和写入固定大小的值进行翻译。固定大小的值可以是固定大小的算术类型(bool,int8,uint8,int16,float32,complex64,...),也可以是只包含固定大小值的数组或结构。
varint函数使用可变长度编码对单个整数值进行编码和解码; 较小的值需要较少的字节。有关规范,请参阅https://developers.google.com/protocol-buffers/docs/encoding。
此包倾向于简化而不是效率。需要高性能序列化的客户端,尤其是大型数据结构的客户端,应该考虑更高级的解决方案,如编码/ gob包或协议缓冲区。
Constants
Variables
func PutUvarint(buf []byte, x uint64) int
func PutVarint(buf []byte, x int64) int
func Read(r io.Reader, order ByteOrder, data interface{}) error
func ReadUvarint(r io.ByteReader) (uint64, error)
func ReadVarint(r io.ByteReader) (int64, error)
func Size(v interface{}) int
func Uvarint(buf []byte) (uint64, int)
func Varint(buf []byte) (int64, int)
func Write(w io.Writer, order ByteOrder, data interface{}) error
type ByteOrder
ByteOrder(Get)ByteOrder(Put)PutUvarint PutVarint Read Uvarint Varint Write Write(Multi)
binary.go varint.go
MaxVarintLenN是varint编码的N位整数的最大长度。
const ( MaxVarintLen16 = 3 MaxVarintLen32 = 5 MaxVarintLen64 = 10)
BigEndian是ByteOrder的大端实现。
var BigEndian bigEndian
LittleEndian是ByteOrder的小端实现。
var LittleEndian littleEndian
func PutUvarint(buf []byte, x uint64) int
PutUvarint将uint64编码到buf中,并返回写入的字节数。如果缓冲区太小,PutUvarint会惊慌失措。
package mainimport ("encoding/binary""fmt")func main() { buf := make([]byte, binary.MaxVarintLen64)for _, x := range []uint64{1, 2, 127, 128, 255, 256} { n := binary.PutUvarint(buf, x) fmt.Printf("%x\n", buf[:n])}}
func PutVarint(buf []byte, x int64) int
PutVarint将int64编码为buf并返回写入的字节数。如果缓冲区太小,PutVarint会惊慌失措。
package mainimport ("encoding/binary""fmt")func main() { buf := make([]byte, binary.MaxVarintLen64)for _, x := range []int64{-65, -64, -2, -1, 0, 1, 2, 63, 64} { n := binary.PutVarint(buf, x) fmt.Printf("%x\n", buf[:n])}}
func Read(r io.Reader, order ByteOrder, data interface{}) error
读取从r读取结构化二进制数据到数据。数据必须是指向固定大小值或固定大小值的指针。从r读取的字节使用指定的字节顺序解码并写入数据的连续字段。当解码布尔值时,零字节被解码为假,并且任何其他非零字节被解码为真。在读入结构时,跳过带空白(_)字段名称的字段的字段数据; 即空白字段名称可用于填充。读入结构时,必须导出所有非空白字段或读取可能会出现混乱。
只有在没有字节被读取的情况下,错误才是EOF。如果在读取一些但不是全部字节后发生EOF,则Read返回ErrUnexpectedEOF。
package mainimport ("bytes""encoding/binary""fmt")func main() {var pi float64 b := []byte{0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40} buf := bytes.NewReader(b) err := binary.Read(buf, binary.LittleEndian, &pi)if err != nil { fmt.Println("binary.Read failed:", err)} fmt.Print(pi)}
func ReadUvarint(r io.ByteReader) (uint64, error)
ReadUvarint从r读取一个编码的无符号整数并将其作为uint64返回。
func ReadVarint(r io.ByteReader) (int64, error)
ReadVarint从r中读取一个已编码的有符号整数并将其作为int64返回。
func Size(v interface{}) int
Size返回Write将生成的值,以便对值v进行编码,该值必须是固定大小的值或固定大小的值片段或指向此类数据的指针。如果v不是这些,则Size返回-1。
func Uvarint(buf []byte) (uint64, int)
Uvarint从buf解码uint64并返回该值和读取的字节数(> 0)。如果发生错误,则该值为0,并且字节数n <= 0意味着:
n == 0: buf too small n < 0: value larger than 64 bits (overflow) and -n is the number of bytes read
package mainimport ("encoding/binary""fmt")func main() { inputs := [][]byte{[]byte{0x01},[]byte{0x02},[]byte{0x7f},[]byte{0x80, 0x01},[]byte{0xff, 0x01},[]byte{0x80, 0x02},}for _, b := range inputs { x, n := binary.Uvarint(b)if n != len(b) { fmt.Println("Uvarint did not consume all of in")} fmt.Println(x)}}
func Varint(buf []byte) (int64, int)
Varint从buf解码int64并返回该值和读取的字节数(> 0)。如果发生错误,则值为0,并且字节数n <= 0,其含义如下:
n == 0: buf too small n < 0: value larger than 64 bits (overflow) and -n is the number of bytes read
package mainimport ("encoding/binary""fmt")func main() { inputs := [][]byte{[]byte{0x81, 0x01},[]byte{0x7f},[]byte{0x03},[]byte{0x01},[]byte{0x00},[]byte{0x02},[]byte{0x04},[]byte{0x7e},[]byte{0x80, 0x01},}for _, b := range inputs { x, n := binary.Varint(b)if n != len(b) { fmt.Println("Varint did not consume all of in")} fmt.Println(x)}}
func Write(w io.Writer, order ByteOrder, data interface{}) error
写将数据的二进制表示写入w。数据必须是固定大小的值或固定大小的值片段,或指向这些数据的指针。布尔值编码为一个字节:1为真,0为假。写入w的字节使用指定的字节顺序进行编码,并从数据的连续字段中读取。在编写结构时,将为具有空白(_)字段名称的字段写入零值。
package mainimport ("bytes""encoding/binary""fmt""math")func main() { buf := new(bytes.Buffer)var pi float64 = math.Pi err := binary.Write(buf, binary.LittleEndian, pi)if err != nil { fmt.Println("binary.Write failed:", err)} fmt.Printf("% x", buf.Bytes())}
package mainimport ("bytes""encoding/binary""fmt")func main() { buf := new(bytes.Buffer)var data = []interface{}{uint16(61374),int8(-54),uint8(254),}for _, v := range data { err := binary.Write(buf, binary.LittleEndian, v)if err != nil { fmt.Println("binary.Write failed:", err)}} fmt.Printf("%x", buf.Bytes())}
ByteOrder指定如何将字节序列转换为16,32或64位无符号整数。
type ByteOrder interface { Uint16([]byte) uint16 Uint32([]byte) uint32 Uint64([]byte) uint64 PutUint16([]byte, uint16) PutUint32([]byte, uint32) PutUint64([]byte, uint64) String() string}
package mainimport ("encoding/binary""fmt")func main() { b := []byte{0xe8, 0x03, 0xd0, 0x07} x1 := binary.LittleEndian.Uint16(b[0:]) x2 := binary.LittleEndian.Uint16(b[2:]) fmt.Printf("%#04x %#04x\n", x1, x2)}
package mainimport ("encoding/binary""fmt")func main() { b := make([]byte, 4) binary.LittleEndian.PutUint16(b[0:], 0x03e8) binary.LittleEndian.PutUint16(b[2:], 0x07d0) fmt.Printf("% x\n", b)}