Overview

包binary实现了简单数字和字节序列的转换,以及各种编码和解码 数字由读取和写入固定大小的值转化,固定大小值是算术类型(bool,int8,uint8,int16,uint16,float32, complex64, ...)或数组或包含固定大小值的结构体 varint函数编码和解码单整型值使用可变长度编码,较小的值占用的字节较小
该包有利于简单而非高效,用户要求较高性能的序列化,特别是对于较大的数据结构,应该选择更先进的方案,比如encoding/gob或protocol buffers

常量(Constants)

MaxVarintLenN是N-bit整型可变编码的最大长度
const (
    MaxVarintLen16 = 3
    MaxVarintLen32 = 5
    MaxVarintLen64 = 10
)

变量(Variables)

BigEndian是ByteOrder的大端实现,LittleEndian是ByteOrder的小端实现
var BigEndian bigEndian
var LittleEndian littleEndian

Functions

func PutUvarint(buf []byte, x uint64) int

将x放入缓冲区,返回写入的字节,如果缓冲区太小,将会panic

func PutVarint(buf []byte, x int64) int

将x放入缓冲区,返回写入的字节,如果缓冲区太小,将会panic

func Read(r io.Reader, order ByteOrder, data interface{}) error

Read从r读取二进制结构数据到data,Data必须是固定大小值的指针或固定大小值的切片,Bytes从r读取使用指定字节序解码写入连续的数据字段,当解码boolean时,0被解码为false,非0值被解码为true,当读取到结构中,数据字段带"_"的字段名会被跳过,例如,带blank(_)的名字字段可能会被用来填充,当读取到结构体时,所有的非空白字段必须导出否则Read panic EOF error当无数据可读,如果未读取所有bytes出现EOF,返回ErrUnexpectedEOF
package main
import (
	"encoding/binary"
	"fmt"
	"bytes"
	"math"
)
type Constants struct {
	Pi float64
	E float64
}
func (c Constants) String() string {
	return fmt.Sprintf("Pi: %1.5f, E: %1.9f", c.Pi, c.E)
}
func main() {
	buf := new(bytes.Buffer)
	err := binary.Write(buf, binary.BigEndian, Constants {
		Pi: math.Pi,
		E: math.E,
	})
	if err != nil {
		fmt.Println(err)
	}
	var constants Constants
	err = binary.Read(buf, binary.BigEndian, &constants)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(constants.String())
}

func ReadUvarint(r io.ByteReader) (uint64, error)

从r读取一个编码的无符号整型并返回

func ReadVarint(r io.ByteReader) (int64, error)

从r读取一个编码的整型并返回

func Size(v interface{}) int

Size返回编码v需要多少字节,v必须是一个固定大小的值,或固定大小值的切片,或这种数据的指针,如果v不是这些,Size返回-1

func Uvarint(buf []byte) (uint64, int)

Uvarint解码buf并返回数据和读取的数据大小,如果错误发生,返回值value为0和大小n <= 0(n ==0表示buf太小, n < 0表示value超过了64位,-n表示读取的数据大小)

func Varint(buf []byte) (int64, int)

Varint解码buf并返回数据和读取的数据大小,如果错误发生,返回值value为0且大小 <= 0(n ==0表示buf太小,n < 0表示value超过了64位,-n表示读取的数据大小)

func Write(w io.Writer, order ByteOrder, data interface{}) error

Write写入data的二进制数据到w,Data必须是固定大小的值或固定大小值的切片,或者指向以上的切片,Boolean编码为1 byte,1表示true,0表示false,Bytes使用指定字节序编码进w,当写入结构体时,带blanl(_)的字段名被写入zero value
package main

import (
	"encoding/binary"
	"fmt"
)

func main() {
	var udata uint64 = 1998
	var idata int64 = -300
	buf := make([]byte, binary.Size(&udata))
	_ = binary.PutUvarint(buf, udata)
	uvalue, _ := binary.Uvarint(buf)
	fmt.Println(uvalue)
	buf = make([]byte, binary.Size(&idata))
	_ = binary.PutVarint(buf, idata)
	ivalue, _ := binary.Varint(buf)
	fmt.Println(ivalue)
}

ByteOrder

ByteOrder指定了如何转换字节序列到16-,32-,64-bit无符号整型
type ByteOrder interface {
    Uint16([]byte) uint16
    Uint32([]byte) uint32
    Uint64([]byte) uint64
    PutUint16([]byte, uint16)
    PutUint32([]byte, uint32)
    PutUint64([]byte, uint64)
    String() string
}

Example

package main
import (
	"encoding/binary"
	"fmt"
)

func main() {
	var udata uint16 = 257
	buf := make([]byte, binary.Size(&udata))
	binary.BigEndian.PutUint16(buf, udata)
	value := binary.BigEndian.Uint16(buf)
	fmt.Println(value)
	udata = 322
	binary.LittleEndian.PutUint16(buf,udata)
	value = binary.LittleEndian.Uint16(buf)
	fmt.Println(value)
}