★bufio | bufio 包实现了带缓存的I/O操作.
golang界里我老八,今天给大家看个bufio。bufio包实现了带缓存的I/O,把io.Reader或io.Writer封装成更牛逼的对象
bufio
bufio包内没有接口定义,只有结构体:
1. bufio.Reader
内部全私有变量,通过如下方法创建:
- NewReader(rd io.Reader) *Reader
:调用NewReaderSize创建defaultBufSize大小(4096B)的bufReader
- NewReaderSize(rd io.Reader, size int) *Reader
结构体定义如下:
type Reader struct {
buf []byte
rd io.Reader // reader provided by the client
r, w int // buf read and write positions
err error
lastByte int // last byte read for UnreadByte; -1 means invalid
lastRuneSize int // size of last rune read for UnreadRune; -1 means invalid
}
感觉和io.SectionReader比较像,只是bufio.Reader自带缓存。
bufio.Reader实现的方法有,有读取为类型,写至,还有seek操作比如Peek(获取下n个字节),Discard(跳过n个字节),UnreadByte(指针回溯)。
2. bufio.Writer
和bufio.Reader尿性一样,就不看了,用到再说
3. bufio.Scaner
作用是用一个SplitFunc函数(默认为ScanLines)从r中读数据。有个成员叫token,作用为储存通过split函数返回的最后一个片段(可能叫fragment更好点吧?
看一下splitFunc函数的一个实现ScanLine:
func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error) {
if atEOF && len(data) == 0 {
return 0, nil, nil
}
if i := bytes.IndexByte(data, '\n'); i >= 0 {
// We have a full newline-terminated line.
return i + 1, dropCR(data[0:i]), nil
}
// If we're at EOF, we have a final, non-terminated line. Return it.
if atEOF {
return len(data), dropCR(data), nil
}
// Request more data.
return 0, nil, nil
}
- data:指定的buf区,说白了就是有数据的一个数组,在Scan()里是这么调用的:
advance, token, err := s.split(s.buf[s.start:s.end], s.err != nil)
- atEOF:是否读到字节流尾部
- advance:游标推进的大小,在
(s *Scanner) advance(n int) bool
被使用这个函数作用是判断advance是否合法并且前进游标 - token:读到的字节数组
- err:错误
函数寻找'\n'的位置,然后返回包括\n的长度即游标推进值,但返回token数组不包括'\n'
- bufio.ReadWriter
在代码中同时存在bufio.Reader和bufio.Writer时可以发动魔法卡融合。
type ReadWriter struct {
*Reader
*Writer
}
可以把数据从Reader WriteTo 到 Writer中,也可以让Writer ReadFrom Reader。