★bufio | bufio 包實(shí)現(xiàn)了帶緩存的I/O操作.
golang界里我老八,今天給大家看個bufio覆劈。bufio包實(shí)現(xiàn)了帶緩存的I/O荔睹,把io.Reader或io.Writer封裝成更牛逼的對象
bufio
bufio包內(nèi)沒有接口定義揖盘,只有結(jié)構(gòu)體:
1. bufio.Reader
內(nèi)部全私有變量,通過如下方法創(chuàng)建:
- NewReader(rd io.Reader) *Reader
:調(diào)用NewReaderSize創(chuàng)建defaultBufSize大泻笆健(4096B)的bufReader
- NewReaderSize(rd io.Reader, size int) *Reader
結(jié)構(gòu)體定義如下:
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實(shí)現(xiàn)的方法有岔留,有讀取為類型夏哭,寫至,還有seek操作比如Peek(獲取下n個字節(jié))献联,Discard(跳過n個字節(jié))竖配,UnreadByte(指針回溯)。
2. bufio.Writer
和bufio.Reader尿性一樣里逆,就不看了进胯,用到再說
3. bufio.Scaner
作用是用一個SplitFunc函數(shù)(默認(rèn)為ScanLines)從r中讀數(shù)據(jù)。有個成員叫token原押,作用為儲存通過split函數(shù)返回的最后一個片段(可能叫fragment更好點(diǎn)吧胁镐?
看一下splitFunc函數(shù)的一個實(shí)現(xiàn)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區(qū),說白了就是有數(shù)據(jù)的一個數(shù)組诸衔,在Scan()里是這么調(diào)用的:
advance, token, err := s.split(s.buf[s.start:s.end], s.err != nil)
- atEOF:是否讀到字節(jié)流尾部
- advance:游標(biāo)推進(jìn)的大小盯漂,在
(s *Scanner) advance(n int) bool
被使用這個函數(shù)作用是判斷advance是否合法并且前進(jìn)游標(biāo) - token:讀到的字節(jié)數(shù)組
- err:錯誤
函數(shù)尋找'\n'的位置,然后返回包括\n的長度即游標(biāo)推進(jìn)值署隘,但返回token數(shù)組不包括'\n'
- bufio.ReadWriter
在代碼中同時存在bufio.Reader和bufio.Writer時可以發(fā)動魔法卡融合宠能。
type ReadWriter struct {
*Reader
*Writer
}
可以把數(shù)據(jù)從Reader WriteTo 到 Writer中,也可以讓W(xué)riter ReadFrom Reader磁餐。