bytes库学习


其实我一直觉得Bytes和strings没啥区别,好吧,所以来看一看

Reader类型

bytes 包下的 Reader 类型实现了 io 包下的 Reader, ReaderAt, RuneReader, RuneScanner, ByteReader, ByteScanner, ReadSeeker, Seeker, WriterTo 等多个接口。主要用于 Read 数据。

a Reader is read-only and supports seeking

The zero value for Reader operates like a Reader of an empty slice.

所以不妨把他理解成一个储物间,要往里面放东西,找东西

1
2
3
4
5
type Reader struct {
s []byte
i int64 // 当前读取下标
prevRune int // 前一个字符的下标,也可能 < 0
}

初始化签名

1
func NewReader(b []byte) *Reader

example

1
2
3
4
5
6
7
8
9
10
11
12
13
func B() {
x := []byte("hello world")

r1 := bytes.NewReader(x) // 初始化
d1 := make([]byte, 5)
n, _ := r1.Read(d1) // 存入数据
fmt.Println(string(d1), "xxx", n)

x2 := []byte("hehheheheheh")
r1.Reset(x2) // 重新输入元素
n1, _ := r1.Read(d1)
fmt.Println(string(d1), "xxx", n1)
}
1
2
3
 # output :
hello xxx 5
hehhe xxx 5
1
func (r *Reader) Len() int   // 读取的是字节,如果是汉字,一个汉字不是一个字节

读取

Reader包含了一些读取的方法,实现了io包下的接口

1
2
3
4
5
6
7
8
9
func (r *Reader) Read(b []byte) (n int, err error) 
func (r *Reader) ReadByte() (byte, error)
func (r *Reader) ReadRune() (ch rune, size int, err error)
func (r *Reader) WriteTo(w io.Writer) (n int64, err error)
func (r *Reader) UnreadByte()
func (r *Reader) UnreadRune()
// ReadAt reads len(p) bytes into p starting at offset off in the underlying input source.
func (r *Reader) ReadAt(b []byte, off int64) (n int, err error)
func (r *Reader) Seek(offset int64, whence int) (int64, error)

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
func main() {
x := []byte("你好, 世界")
r1 := bytes.NewReader(x)
// 获取 ascll码下的 值
ch, size, _ := r1.ReadRune()
fmt.Println(size, string(ch))
_ = r1.UnreadRune()
ch, size, _ = r1.ReadRune()
fmt.Println(size, string(ch))
_ = r1.UnreadRune()
// 获取字节噢
by, _ := r1.ReadByte()
fmt.Println(by)
_ = r1.UnreadByte()
by, _ = r1.ReadByte()
fmt.Println(by)
_ = r1.UnreadByte()
// 从 index = 0 开始获取值
d1 := make([]byte, 6)
n, _ := r1.Read(d1)
fmt.Println(n, string(d1))
// 自定义index获取值
d2 := make([]byte, 12)
n, _ = r1.ReadAt(d2, 6)
fmt.Println(n, string(d2))
// 使用buffer
w1 := new(bytes.Buffer)
_, _ = r1.Seek(0, 0)
_, _ = r1.WriteTo(w1)
fmt.Println(w1.String())

}

Buffer类型

1
2
3
4
5
type Buffer struct {
buf []byte
off int
lastRead readOp
}

bytes.Buffer 类型,该类型实现了 io 包下的 ByteScanner, ByteWriter, ReadWriter, Reader, ReaderFrom, RuneReader, RuneScanner, StringWriter, Writer, WriterTo 等接口,可以方便的进行读写操作。

off (offset),表示可以从特定索引出发遍历

简单读取

1
2
3
4
5
6
7
8
9
10
11
	b := bytes.NewBuffer([]byte("Hello, World!"))
c := bytes.NewBufferString("Hello, World!")
d := bytes.Buffer{}

fmt.Println(b)
fmt.Println(b.String())
fmt.Println(c)
fmt.Println(c.String())
fmt.Println(d)
fmt.Println(d.String())
}
1
2
3
4
5
6
# output:
Hello, World!
Hello, World!
Hello, World!
Hello, World!
{[] 0 0}

特殊

1
2
3
4
5
6
// 读取到字节 delim 后,以字节数组的形式返回该字节及前面读取到的字节。如果遍历 b.buf 也找不到匹配的字节,则返回错误(一般是 EOF)
func (b *Buffer) ReadBytes(delim byte) (line []byte, err error)
// 读取到字节 delim 后,以字符串的形式返回该字节及前面读取到的字节。如果遍历 b.buf 也找不到匹配的字节,则返回错误(一般是 EOF)
func (b *Buffer) ReadString(delim byte) (line string, err error)
// 截断 b.buf , 舍弃 b.off+n 之后的数据。n == 0 时,调用 Reset 方法重置该对象,当 n 越界时(n < 0 || n > b.Len() )方法会触发 panic.
func (b *Buffer) Truncate(n int)

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
func main() {
bu := bytes.NewBuffer([]byte("Hello, World!"))

line, _ := bu.ReadString('o')
fmt.Println(line)

readByte, _ := bu.ReadBytes('o')
fmt.Println(readByte)
fmt.Println(bu.String())

bu.Truncate(2)
b, _ := bu.ReadBytes('o')
fmt.Println(b)
fmt.Println(string(b))
}
1
2
3
4
5
Hello
[44 32 87 111]
rld!
[114 108]
rl