Go基礎篇【第4篇】: 內置庫模塊 bufio

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

type Reader struct {
    // 內含隱藏或非導出字段
}

Reader實現了給一個io.Reader接口對象附加緩衝。這個就是封裝後返回高速讀寫對象ui

func NewReader

func NewReader(rd io.Reader) *Reader

NewReader建立一個具備默認大小緩衝、從r讀取的*Reader。建立一個用戶接受普通數據的NewReader對象,接收的參數是一個實現了普通io.Reader的接口。從字面意義也能看出接收的是一個io.Reader 返回的也是一個 Reader編碼

func NewReaderSize

func NewReaderSize(rd io.Reader, size int) *Reader

NewReaderSize建立一個具備最少有size尺寸的緩衝、從r讀取的*Reader。若是參數r已是一個具備足夠大緩衝的* Reader類型值,會返回r。和上一個的差異是建立時設置了高速緩衝區的大小。spa

func (*Reader) Reset

func (b *Reader) Reset(r io.Reader)

Reset丟棄緩衝中的數據,清除任何錯誤,將b重設爲其下層從r讀取數據。清空(高速)緩衝區中的數據翻譯

func (*Reader) Buffered

func (b *Reader) Buffered() int

Buffered返回緩衝中現有的可讀取的字節數。統計(高速)緩衝區中的字節數,並返回

func (*Reader) Peek

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 (*Reader) ReadByte 

func (b *Reader) ReadByte() (c byte, err error)

ReadByte讀取並返回一個字節。若是沒有可用的數據,會返回錯誤。

// ReadByte 從 b 中讀出一個字節並返回
// 若是 b 中無可讀數據,則返回一個錯誤

func (*Reader) UnreadByte

func (b *Reader) UnreadByte() error

UnreadByte吐出最近一次讀取操做讀取的最後一個字節。(只能吐出最後一個,屢次調用會出問題)

// UnreadByte 撤消最後一次讀出的字節
// 只有最後讀出的字節能夠被撤消
// 不管任何操做,只要有內容被讀出,就能夠用 UnreadByte 撤消一個字節

func (*Reader) ReadRune

func (b *Reader) ReadRune() (r rune, size int, err error)

ReadRune讀取一個utf-8編碼的unicode碼值,返回該碼值、其編碼長度和可能的錯誤。若是utf-8編碼非法,讀取位置只移動1字節,返回U+FFFD,返回值size爲1而err爲nil。若是沒有可用的數據,會返回錯誤。

func (*Reader) UnreadRune

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 (*Reader) ReadBytes

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 (*Reader) ReadString

func (b *Reader) ReadString(delim byte) (line string, err error)

ReadString讀取直到第一次遇到delim字節,返回一個包含已讀取的數據和delim字節的字符串。若是ReadString方法在讀取到delim以前遇到了錯誤,它會返回在錯誤以前讀取的數據以及該錯誤(通常是io.EOF)。當且僅當ReadString方法返回的切片不以delim結尾時,會返回一個非nil的錯誤。

func (*Reader) ReadLine

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 (*Reader) ReadSlice

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 (*Reader) WriteTo

func (b *Reader) WriteTo(w io.Writer) (n int64, err error)

WriteTo方法實現了io.WriterTo接口。

type Writer

type Writer struct {
    // 內含隱藏或非導出字段
}

Writer實現了爲io.Writer接口對象提供緩衝。若是在向一個Writer類型值寫入時遇到了錯誤,該對象將再也不接受任何數據,且全部寫操做都會返回該錯誤。在說有數據都寫入後,調用者有義務調用Flush方法以保證全部的數據都交給了下層的io.Writer。

Example

func NewWriter

func NewWriter(w io.Writer) *Writer

NewWriter建立一個具備默認大小緩衝、寫入w的*Writer。

func NewWriterSize

func NewWriterSize(w io.Writer, size int) *Writer

NewWriterSize建立一個具備最少有size尺寸的緩衝、寫入w的*Writer。若是參數w已是一個具備足夠大緩衝的*Writer類型值,會返回w。

func (*Writer) Reset

func (b *Writer) Reset(w io.Writer)

Reset丟棄緩衝中的數據,清除任何錯誤,將b重設爲將其輸出寫入w。

func (*Writer) Buffered

func (b *Writer) Buffered() int

Buffered返回緩衝中已使用的字節數。

func (*Writer) Available

func (b *Writer) Available() int

Available返回緩衝中還有多少字節未使用。

func (*Writer) Write

func (b *Writer) Write(p []byte) (nn int, err error)

Write將p的內容寫入緩衝。返回寫入的字節數。若是返回值nn < len(p),還會返回一個錯誤說明緣由。

func (*Writer) WriteString

func (b *Writer) WriteString(s string) (int, error)

WriteString寫入一個字符串。返回寫入的字節數。若是返回值nn < len(s),還會返回一個錯誤說明緣由。

func (*Writer) WriteByte

func (b *Writer) WriteByte(c byte) error

WriteByte寫入單個字節。

func (*Writer) WriteRune

func (b *Writer) WriteRune(r rune) (size int, err error)

WriteRune寫入一個unicode碼值(的utf-8編碼),返回寫入的字節數和可能的錯誤。

func (*Writer) Flush

func (b *Writer) Flush() error

Flush方法將緩衝中的數據寫入下層的io.Writer接口。

func (*Writer) ReadFrom

func (b *Writer) ReadFrom(r io.Reader) (n int64, err error)

ReadFrom實現了io.ReaderFrom接口。

############################################################

type ReadWriter

type ReadWriter struct {
    *Reader
    *Writer
}

ReadWriter類型保管了指向Reader和Writer類型的指針,(所以)實現了io.ReadWriter接口。

func NewReadWriter

func NewReadWriter(r *Reader, w *Writer) *ReadWriter

NewReadWriter申請建立一個新的、將讀寫操做分派給r和w 的ReadWriter。

type SplitFunc

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

func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error)

ScanBytes是用於Scanner類型的分割函數(符合SplitFunc),本函數會將每一個字節做爲一個token返回。

func ScanRunes

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

func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error)

ScanRunes是用於Scanner類型的分割函數(符合SplitFunc),本函數會將空白(參見unicode.IsSpace)分隔的片斷(去掉先後空白後)做爲一個token返回。本函數永遠不會返回空字符串。

func ScanLines

func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error)

ScanRunes是用於Scanner類型的分割函數(符合SplitFunc),本函數會將每一行文本去掉末尾的換行標記做爲一個token返回。返回的行能夠是空字符串。換行標記爲一個可選的回車後跟一個必選的換行符。最後一行即便沒有換行符也會做爲一個token返回。

type Scanner

type Scanner struct {
    // 內含隱藏或非導出字段
}

Scanner類型提供了方便的讀取數據的接口,如從換行符分隔的文本里讀取每一行。

成功調用的Scan方法會逐步提供文件的token,跳過token之間的字節。token由SplitFunc類型的分割函數指定;默認的分割函數會將輸入分割爲多個行,並去掉行尾的換行標誌。本包預約義的分割函數能夠將文件分割爲行、字節、unicode碼值、空白分隔的word。調用者能夠定製本身的分割函數。

掃描會在抵達輸入流結尾、遇到的第一個I/O錯誤、token過大不能保存進緩衝時,不可恢復的中止。當掃描中止後,當前讀取位置可能會遠在最後一個得到的token後面。須要更多對錯誤管理的控制或token很大,或必須從reader連續掃描的程序,應使用bufio.Reader代替。

Example (Custom)
Example (Lines)
Example (Words)

func NewScanner

func NewScanner(r io.Reader) *Scanner

NewScanner建立並返回一個從r讀取數據的Scanner,默認的分割函數是ScanLines。

func (*Scanner) Split

func (s *Scanner) Split(split SplitFunc)

Split設置該Scanner的分割函數。本方法必須在Scan以前調用。

func (*Scanner) Scan

func (s *Scanner) Scan() bool

Scan方法獲取當前位置的token(該token能夠經過Bytes或Text方法得到),並讓Scanner的掃描位置移動到下一個token。當掃描由於抵達輸入流結尾或者遇到錯誤而中止時,本方法會返回false。在Scan方法返回false後,Err方法將返回掃描時遇到的任何錯誤;除非是io.EOF,此時Err會返回nil。

func (*Scanner) Bytes

func (s *Scanner) Bytes() []byte

Bytes方法返回最近一次Scan調用生成的token。底層數組指向的數據可能會被下一次Scan的調用重寫。

func (*Scanner) Text

func (s *Scanner) Text() string

Bytes方法返回最近一次Scan調用生成的token,會申請建立一個字符串保存token並返回該字符串。

func (*Scanner) Err

func (s *Scanner) Err() error

Err返回Scanner遇到的第一個非EOF的錯誤。

相關文章
相關標籤/搜索