bufio包實現了有緩衝的I/O。它包裝一個io.Reader或io.Writer接口對象,建立另外一個也實現了該接口,且同時還提供了緩衝和一些文本I/O的幫助函數的對象。git
即:爲了解決CPU與磁盤IO速度不匹配問題,咱們利用buffio將提供給CPU的數據緩存到buff內存中,而後進行讀寫,提升讀寫效率。因此咱們就須要建立一個buffio對象,而後將須要操做的數據傳遞給它,而後再封裝返回一個高速讀寫的buffio對象。github
因此能夠總結爲如下步驟:golang
1. 建立一個buffio對象。數組
2. 將一個普通讀取數據傳遞給上一個高速buffio對象。緩存
3. buffio接收數據後返回一個高速操做對象。函數
type Reader struct { // 內含隱藏或非導出字段 }
Reader實現了給一個io.Reader接口對象附加緩衝。這個就是封裝後返回高速讀寫對象ui
func NewReader(rd io.Reader) *Reader
NewReader建立一個具備默認大小緩衝、從r讀取的*Reader。建立一個用戶接受普通數據的NewReader對象,接收的參數是一個實現了普通io.Reader的接口。從字面意義也能看出接收的是一個io.Reader 返回的也是一個 Reader編碼
func NewReaderSize(rd io.Reader, size int) *Reader
NewReaderSize建立一個具備最少有size尺寸的緩衝、從r讀取的*Reader。若是參數r已是一個具備足夠大緩衝的* Reader類型值,會返回r。和上一個的差異是建立時設置了高速緩衝區的大小。spa
func (b *Reader) Reset(r io.Reader)
Reset丟棄緩衝中的數據,清除任何錯誤,將b重設爲其下層從r讀取數據。清空(高速)緩衝區中的數據翻譯
func (b *Reader) Buffered() int
Buffered返回緩衝中現有的可讀取的字節數。統計(高速)緩衝區中的字節數,並返回
func (b *Reader) Peek(n int) ([]byte, error)
Peek返回輸入流的下n個字節,而不會移動讀取位置。返回的[]byte只在下一次調用讀取操做前合法。若是Peek返回的切片長度比n小,它也會返會一個錯誤說明緣由。若是n比緩衝尺寸還大,返回的錯誤將是ErrBufferFull。
即:返回的若是不是咱們指定的n個字節,不管大小都會報錯
// Peek 返回緩存的一個切片,該切片引用緩存中前 n 字節數據
// 該操做不會將數據讀出,只是引用
// 引用的數據在下一次讀取操做以前是有效的
// 若是引用的數據長度小於 n,則返回一個錯誤信息
// 若是 n 大於緩存的總大小,則返回 ErrBufferFull
// 經過 Peek 的返回值,能夠修改緩存中的數據
// 可是不能修改底層 io.Reader 中的數據
func (b *Reader) ReadByte() (c byte, err error)
ReadByte讀取並返回一個字節。若是沒有可用的數據,會返回錯誤。
// ReadByte 從 b 中讀出一個字節並返回
// 若是 b 中無可讀數據,則返回一個錯誤
func (b *Reader) UnreadByte() error
UnreadByte吐出最近一次讀取操做讀取的最後一個字節。(只能吐出最後一個,屢次調用會出問題)
// UnreadByte 撤消最後一次讀出的字節
// 只有最後讀出的字節能夠被撤消
// 不管任何操做,只要有內容被讀出,就能夠用 UnreadByte 撤消一個字節
func (b *Reader) ReadRune() (r rune, size int, err error)
ReadRune讀取一個utf-8編碼的unicode碼值,返回該碼值、其編碼長度和可能的錯誤。若是utf-8編碼非法,讀取位置只移動1字節,返回U+FFFD,返回值size爲1而err爲nil。若是沒有可用的數據,會返回錯誤。
func (b *Reader) UnreadRune() error
UnreadRune吐出最近一次ReadRune調用讀取的unicode碼值。若是最近一次讀取不是調用的ReadRune,會返回錯誤。(從這點看,UnreadRune比UnreadByte嚴格不少)
// ReadRune 從 b 中讀出一個 UTF8 編碼的字符並返回
// 同時返回該字符的 UTF8 編碼長度
// 若是 UTF8 序列沒法解碼出一個正確的 Unicode 字符
// 則只讀出 b 中的一個字節,並返回 U+FFFD 字符,size 返回 1
func (b *Reader) ReadRune() (r rune, size int, err error)
// UnreadRune 撤消最後一次讀出的 Unicode 字符
// 若是最後一次執行的不是 ReadRune 操做,則返回一個錯誤
// 所以,UnreadRune 比 UnreadByte 更嚴格
func (b *Reader) ReadBytes(delim byte) (line []byte, err error)
ReadBytes讀取直到第一次遇到delim字節,返回一個包含已讀取的數據和delim字節的切片。若是ReadBytes方法在讀取到delim以前遇到了錯誤,它會返回在錯誤以前讀取的數據以及該錯誤(通常是io.EOF)。當且僅當ReadBytes方法返回的切片不以delim結尾時,會返回一個非nil的錯誤。
// ReadBytes 在 b 中查找 delim 並讀出 delim 及其以前的全部數據
// 若是 ReadBytes 在找到 delim 以前遇到錯誤
// 則返回遇到錯誤以前的全部數據,同時返回遇到的錯誤(一般是 io.EOF)
// 只有當 ReadBytes 找不到 delim 時,err 纔不爲 nil
// 對於簡單的用途,使用 Scanner 可能更方便
func (b *Reader) ReadString(delim byte) (line string, err error)
ReadString讀取直到第一次遇到delim字節,返回一個包含已讀取的數據和delim字節的字符串。若是ReadString方法在讀取到delim以前遇到了錯誤,它會返回在錯誤以前讀取的數據以及該錯誤(通常是io.EOF)。當且僅當ReadString方法返回的切片不以delim結尾時,會返回一個非nil的錯誤。
func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error)
ReadLine是一個低水平的行數據讀取原語。大多數調用者應使用ReadBytes('\n')或ReadString('\n')代替,或者使用Scanner。
ReadLine嘗試返回一行數據,不包括行尾標誌的字節。若是行太長超過了緩衝,返回值isPrefix會被設爲true,並返回行的前面一部分。該行剩下的部分將在以後的調用中返回。返回值isPrefix會在返回該行最後一個片斷時才設爲false。返回切片是緩衝的子切片,只在下一次讀取操做以前有效。ReadLine要麼返回一個非nil的line,要麼返回一個非nil的err,兩個返回值至少一個非nil。
返回的文本不包含行尾的標誌字節("\r\n"或"\n")。若是輸入流結束時沒有行尾標誌字節,方法不會出錯,也不會指出這一狀況。在調用ReadLine以後調用UnreadByte會老是吐出最後一個讀取的字節(極可能是該行的行尾標誌字節),即便該字節不是ReadLine返回值的一部分。
func (b *Reader) ReadSlice(delim byte) (line []byte, err error)
ReadSlice讀取直到第一次遇到delim字節,返回緩衝裏的包含已讀取的數據和delim字節的切片。該返回值只在下一次讀取操做以前合法。若是ReadSlice放在在讀取到delim以前遇到了錯誤,它會返回在錯誤以前讀取的數據在緩衝中的切片以及該錯誤(通常是io.EOF)。若是在讀取到delim以前緩衝就被寫滿了,ReadSlice失敗並返回ErrBufferFull。由於ReadSlice的返回值會被下一次I/O操做重寫,調用者應儘可能使用ReadBytes或ReadString替代本法功法。當且僅當ReadBytes方法返回的切片不以delim結尾時,會返回一個非nil的錯誤。
func (b *Reader) WriteTo(w io.Writer) (n int64, err error)
WriteTo方法實現了io.WriterTo接口。
type Writer struct {
// 內含隱藏或非導出字段
}
Writer實現了爲io.Writer接口對象提供緩衝。若是在向一個Writer類型值寫入時遇到了錯誤,該對象將再也不接受任何數據,且全部寫操做都會返回該錯誤。在說有數據都寫入後,調用者有義務調用Flush方法以保證全部的數據都交給了下層的io.Writer。
func NewWriter(w io.Writer) *Writer
NewWriter建立一個具備默認大小緩衝、寫入w的*Writer。
func NewWriterSize(w io.Writer, size int) *Writer
NewWriterSize建立一個具備最少有size尺寸的緩衝、寫入w的*Writer。若是參數w已是一個具備足夠大緩衝的*Writer類型值,會返回w。
func (b *Writer) Reset(w io.Writer)
Reset丟棄緩衝中的數據,清除任何錯誤,將b重設爲將其輸出寫入w。
func (b *Writer) Buffered() int
Buffered返回緩衝中已使用的字節數。
func (b *Writer) Available() int
Available返回緩衝中還有多少字節未使用。
func (b *Writer) Write(p []byte) (nn int, err error)
Write將p的內容寫入緩衝。返回寫入的字節數。若是返回值nn < len(p),還會返回一個錯誤說明緣由。
func (b *Writer) WriteString(s string) (int, error)
WriteString寫入一個字符串。返回寫入的字節數。若是返回值nn < len(s),還會返回一個錯誤說明緣由。
func (b *Writer) WriteByte(c byte) error
WriteByte寫入單個字節。
func (b *Writer) WriteRune(r rune) (size int, err error)
WriteRune寫入一個unicode碼值(的utf-8編碼),返回寫入的字節數和可能的錯誤。
func (b *Writer) Flush() error
Flush方法將緩衝中的數據寫入下層的io.Writer接口。
func (b *Writer) ReadFrom(r io.Reader) (n int64, err error)
ReadFrom實現了io.ReaderFrom接口。
############################################################
type ReadWriter struct { *Reader *Writer }
ReadWriter類型保管了指向Reader和Writer類型的指針,(所以)實現了io.ReadWriter接口。
func NewReadWriter(r *Reader, w *Writer) *ReadWriter
NewReadWriter申請建立一個新的、將讀寫操做分派給r和w 的ReadWriter。
type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error)
SplitFunc類型表明用於對輸出做詞法分析的分割函數。
參數data是還沒有處理的數據的一個開始部分的切片,參數atEOF表示是否Reader接口不能提供更多的數據。返回值是解析位置前進的字節數,將要返回給調用者的token切片,以及可能遇到的錯誤。若是數據不足以(保證)生成一個完整的token,例如須要一整行數據但data裏沒有換行符,SplitFunc能夠返回(0, nil, nil)來告訴Scanner讀取更多的數據寫入切片而後用從同一位置起始、長度更長的切片再試一次(調用SplitFunc類型函數)。
若是返回值err非nil,掃描將終止並將該錯誤返回給Scanner的調用者。
除非atEOF爲真,永遠不會使用空切片data調用SplitFunc類型函數。然而,若是atEOF爲真,data卻多是非空的、且包含着未處理的文本。
func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error)
ScanBytes是用於Scanner類型的分割函數(符合SplitFunc),本函數會將每一個字節做爲一個token返回。
func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error)
ScanRunes是用於Scanner類型的分割函數(符合SplitFunc),本函數會將每一個utf-8編碼的unicode碼值做爲一個token返回。本函數返回的rune序列和range一個字符串的輸出rune序列相同。錯誤的utf-8編碼會翻譯爲U+FFFD = "\xef\xbf\xbd",但只會消耗一個字節。調用者沒法區分正確編碼的rune和錯誤編碼的rune。
func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error)
ScanRunes是用於Scanner類型的分割函數(符合SplitFunc),本函數會將空白(參見unicode.IsSpace)分隔的片斷(去掉先後空白後)做爲一個token返回。本函數永遠不會返回空字符串。
func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error)
ScanRunes是用於Scanner類型的分割函數(符合SplitFunc),本函數會將每一行文本去掉末尾的換行標記做爲一個token返回。返回的行能夠是空字符串。換行標記爲一個可選的回車後跟一個必選的換行符。最後一行即便沒有換行符也會做爲一個token返回。
type Scanner struct {
// 內含隱藏或非導出字段
}
Scanner類型提供了方便的讀取數據的接口,如從換行符分隔的文本里讀取每一行。
成功調用的Scan方法會逐步提供文件的token,跳過token之間的字節。token由SplitFunc類型的分割函數指定;默認的分割函數會將輸入分割爲多個行,並去掉行尾的換行標誌。本包預約義的分割函數能夠將文件分割爲行、字節、unicode碼值、空白分隔的word。調用者能夠定製本身的分割函數。
掃描會在抵達輸入流結尾、遇到的第一個I/O錯誤、token過大不能保存進緩衝時,不可恢復的中止。當掃描中止後,當前讀取位置可能會遠在最後一個得到的token後面。須要更多對錯誤管理的控制或token很大,或必須從reader連續掃描的程序,應使用bufio.Reader代替。
func NewScanner(r io.Reader) *Scanner
NewScanner建立並返回一個從r讀取數據的Scanner,默認的分割函數是ScanLines。
func (s *Scanner) Split(split SplitFunc)
Split設置該Scanner的分割函數。本方法必須在Scan以前調用。
func (s *Scanner) Scan() bool
Scan方法獲取當前位置的token(該token能夠經過Bytes或Text方法得到),並讓Scanner的掃描位置移動到下一個token。當掃描由於抵達輸入流結尾或者遇到錯誤而中止時,本方法會返回false。在Scan方法返回false後,Err方法將返回掃描時遇到的任何錯誤;除非是io.EOF,此時Err會返回nil。
func (s *Scanner) Bytes() []byte
Bytes方法返回最近一次Scan調用生成的token。底層數組指向的數據可能會被下一次Scan的調用重寫。
func (s *Scanner) Text() string
Bytes方法返回最近一次Scan調用生成的token,會申請建立一個字符串保存token並返回該字符串。
func (s *Scanner) Err() error
Err返回Scanner遇到的第一個非EOF的錯誤。