go源码解读-bytes.Reader

bytes.Reader

  • bytes包中的结构体Reader实现的接口包括
    • io.Reader
    • io.ReaderAt
    • io.WriterTo
    • io.Seeker,
    • io.ByteScanner
    • io.RuneScanner

Reader结构体机器方法

  • bytes.Reader可以实现从字节数组中读取数据
  • bytes.Reader是只读的,并且支持查找
  • bytes.Reader的零值等价于从空slice中读取的值
1
2
3
4
5
type Reader struct {
s []byte // 字节数组
i int64 // 当前读取到的索引
prevRune int // 上一个读取的字符的索引
}

Reader结构体的方法

  • Len方法返回Reader结构体中还未读取的部分的字节数
  • Size方法返回Reader结构体中字节数组s的字节数,Size这个方法无论何时调用,返回结果都应该相同
  • Reset方法,初始化Reader为最初从字节b读取的状态,重置方法
1
2
3
4
5
6
7
8
9
10
func (r *Reader) Len() int {
if r.i >= int64(len(r.s)) {
return 0
}
return int(int64(len(r.s)) - r.i)
}
func (r *Reader) Size() int64 { return int64(len(r.s)) }
func (r *Reader) Reset(b []byte) { *r = Reader{b, 0, -1} }
  • 实现io.Reader接口的Read方法,将数据读取到字节数组byte中
1
2
3
4
5
6
7
8
9
func (r *Reader) Read(b []byte) (n int, err error) {
if r.i >= int64(len(r.s)) {
return 0, io.EOF
}
r.prevRune = -1
n = copy(b, r.s[r.i:])
r.i += int64(n)
return
}
  • 实现io.ReaderAt接口的ReadAt方法,从offset的位置开始读取
1
2
3
4
5
6
7
8
9
10
11
12
13
14
func (r *Reader) ReadAt(b []byte, off int64) (n int, err error) {
// cannot modify state - see io.ReaderAt
if off < 0 {
return 0, errors.New("bytes.Reader.ReadAt: negative offset")
}
if off >= int64(len(r.s)) {
return 0, io.EOF
}
n = copy(b, r.s[off:])
if n < len(b) {
err = io.EOF
}
return
}
  • 实现io.ByteReader的ReadByte方法,每次读取一个byte数据
1
2
3
4
5
6
7
8
9
10
// ReadByte implements the interface.
func (r *Reader) ReadByte() (byte, error) {
r.prevRune = -1
if r.i >= int64(len(r.s)) {
return 0, io.EOF
}
b := r.s[r.i]
r.i++
return b, nil
}
  • 实现io.ByteScanner接口的UnreadByte方法,将上一个读取过的byte设置为未读取,及r.i–
1
2
3
4
5
6
7
8
func (r *Reader) UnreadByte() error {
if r.i <= 0 {
return errors.New("bytes.Reader.UnreadByte: at beginning of slice")
}
r.prevRune = -1
r.i--
return nil
}
  • 实现io.RuneReader接口的ReadRune方法,从byte中读取一个字符
1
2
3
4
5
6
7
8
9
10
11
12
13
14
func (r *Reader) ReadRune() (ch rune, size int, err error) {
if r.i >= int64(len(r.s)) {
r.prevRune = -1
return 0, 0, io.EOF
}
r.prevRune = int(r.i)
if c := r.s[r.i]; c < utf8.RuneSelf {
r.i++
return rune(c), 1, nil
}
ch, size = utf8.DecodeRune(r.s[r.i:])
r.i += int64(size)
return
}
  • 实现io.RuneScanner接口的UnreadRune方法,将上一个字符,设置为未读,r.i = int64(r.prevRune)即可
1
2
3
4
5
6
7
8
9
10
11
func (r *Reader) UnreadRune() error {
if r.i <= 0 {
return errors.New("bytes.Reader.UnreadRune: at beginning of slice")
}
if r.prevRune < 0 {
return errors.New("bytes.Reader.UnreadRune: previous operation was not ReadRune")
}
r.i = int64(r.prevRune)
r.prevRune = -1
return nil
}
  • 实现io.Seeker的Seek方法
    • whence场景包括开头,结尾,和当前指向的index
    • 返回的是要查找的索引值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
func (r *Reader) Seek(offset int64, whence int) (int64, error) {
r.prevRune = -1
var abs int64
switch whence {
case io.SeekStart:
abs = offset
case io.SeekCurrent:
abs = r.i + offset
case io.SeekEnd:
abs = int64(len(r.s)) + offset
default:
return 0, errors.New("bytes.Reader.Seek: invalid whence")
}
if abs < 0 {
return 0, errors.New("bytes.Reader.Seek: negative position")
}
r.i = abs
return abs, nil
}
  • 实现io.WriterTo接口的WriteTo方法,将i之后的字节切片写入w中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
func (r *Reader) WriteTo(w io.Writer) (n int64, err error) {
r.prevRune = -1
if r.i >= int64(len(r.s)) {
return 0, nil
}
b := r.s[r.i:]
m, err := w.Write(b)
if m > len(b) {
panic("bytes.Reader.WriteTo: invalid Write count")
}
r.i += int64(m)
n = int64(m)
if m != len(b) && err == nil {
err = io.ErrShortWrite
}
return
}

初始化Reader方法

  • NewReader创建一个读取b的Reader对象
1
2
// NewReader returns a new Reader reading from b.
func NewReader(b []byte) *Reader { return &Reader{b, 0, -1} }
Donate comment here