encoding/binary
Package binary
import "encoding/binary"
概述
索引
示例
概述
软件包二进制实现了数字和字节序列之间的简单转换以及 varint 的编码和解码。
数字通过读取和写入固定大小的值进行翻译。固定大小的值可以是固定大小的算术类型(bool,int8,uint8,int16,float32,complex64,...),也可以是只包含固定大小值的数组或结构。
varint 函数使用可变长度编码对单个整数值进行编码和解码;较小的值需要较少的字节。有关规范,请参阅https://developers.google.com/protocol-buffers/docs/encoding。
此包倾向于简化而不是效率。需要高性能序列化的客户端,尤其是大型数据结构的客户端,应该考虑更高级的解决方案,如 encoding/gob 包或协议缓冲区。
索引
常量
变量
- 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)
包文件
常量
MaxVarintLenN 是 varint 编码的 N 位整数的最大长度。
const (
MaxVarintLen16 = 3
MaxVarintLen32 = 5
MaxVarintLen64 = 10
)
变量
BigEndian 是 ByteOrder 的大端实现。
var BigEndian bigEndian
LittleEndian 是 ByteOrder 的小端实现。
var LittleEndian littleEndian
func PutUvarint(查看源代码)
func PutUvarint(buf []byte, x uint64) int
PutUvarint 将 uint64 编码到 buf 中,并返回写入的字节数。如果缓冲区太小,PutUvarint 会慌乱(panic)。
示例
package main
import (
"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(查看源代码)
func PutVarint(buf []byte, x int64) int
PutVarint 将 int64 编码为 buf 并返回写入的字节数。如果缓冲区太小,PutVarint 会慌乱(panic)。
示例
package main
import (
"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(查看源代码)
func Read(r io.Reader, order ByteOrder, data interface{}) error
读取从 r 读取结构化二进制数据到数据。数据必须是指向固定大小值或固定大小值的指针。从 r 读取的字节使用指定的字节顺序解码并写入数据的连续字段。当解码布尔值时,零字节被解码为假,并且任何其他非零字节被解码为真。在读入结构时,跳过带空白(_)字段名称的字段的字段数据;即空白字段名称可用于填充。读入结构时,必须导出所有非空白字段或读取可能会出现混乱。
只有在没有字节被读取的情况下,错误才是 EOF。如果在读取一些但不是全部字节后发生 EOF,则 Read 返回 ErrUnexpectedEOF。
示例
package main
import (
"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(查看源代码)
func ReadUvarint(r io.ByteReader) (uint64, error)
ReadUvarint 从 r 读取一个编码的无符号整数并将其作为 uint64 返回。
func ReadVarint(查看源代码)
func ReadVarint(r io.ByteReader) (int64, error)
ReadVarint 从 r 中读取一个已编码的有符号整数并将其作为 int64 返回。
func Size(查看源代码)
func Size(v interface{}) int
Size 返回 Write 将生成的值,以便对值 v 进行编码,该值必须是固定大小的值或固定大小的值片段或指向此类数据的指针。如果 v 不是这些,则 Size 返回-1。
func Uvarint(查看源代码)
func Uvarint(buf []byte) (uint64, int)
Uvarint 从 buf 解码 uint64 并返回该值和读取的字节数(> 0)。如果发生错误,则该值为0,并且字节数n <= 0意味着:
n == 0:buf太小了
n <0:大于64位的值(溢出)
和-n是读取的字节数
示例
package main
import (
"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(查看源代码)
func Varint(buf []byte) (int64, int)
Varint 从 buf 解码 int64 并返回该值和读取的字节数(> 0)。如果发生错误,则值为0,并且字节数 n <= 0,其含义如下:
n == 0:buf太小了
n <0:大于64位的值(溢出)
和-n是读取的字节数
示例
package main
import (
"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(查看源代码)
func Write(w io.Writer, order ByteOrder, data interface{}) error
写将数据的二进制表示写入 w。数据必须是固定大小的值或固定大小的值片段,或指向这些数据的指针。布尔值编码为一个字节:1 为真,0 为假。写入 w 的字节使用指定的字节顺序进行编码,并从数据的连续字段中读取。在编写结构时,将为具有空白(_)字段名称的字段写入零值。
示例
package main
import (
"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())
}
示例(Multi)
package main
import (
"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())
}
type ByteOrder(查看源代码)
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
}
示例(Get)
package main
import (
"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)
}
示例 (Put)
package main
import (
"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)
}