GO bufio解讀

Reader

// Reader implements buffering for an io.Reader object.
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
}

Reader的作用是爲io.Reader提供一個buffer。Go提供了兩個構造函數來創建Reader。

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

func NewReaderSize(rd io.Reader, size int) *Reader
如果rd本身就是Reader實例,並且len(rd.buf) >= size, 那麼直接以rd作爲返回值
如果size < 16, 返回一個buf長度爲16的新Reader實例

func NewReader(rd io.Reader) *Reader
相當於NewReaderSize(rd, 4096)

其他操作函數解釋如下:

func (b *Reader) Size() int  // 返回Reader中buf切片的長度
func (b *Reader) Reset(r io.Reader)  // 重置Reader中的rd,並將lastByte和lastRuneByte設爲-1
func (b *Reader) Peek(n int) ([]byte, error) //從buf中取出n個字節。其與Read的不同點在於,Peek後不能執行UnreadByte和UnreadRune。因爲Peek執行後會將lastByte和lastRuneSize置爲-1,UnreadByte和UnreadRune執行時會先檢查這兩個字段,如果爲-1則報錯
func (b *Reader) Discard(n int) (discarded int, err error) // 拋棄未讀的n字節數據,實質是將r向後移動n個位置
func (b *Reader) Read(p []byte) (n int, err error) //讀取buf中的數據並寫入到p中,返回實際讀取的字節數。如果讀到文件末尾,err將被設置爲io.EOF
func (b *Reader) ReadByte() (byte, error) //讀一個字節
func (b *Reader) UnreadByte() error //將上一個讀取的字節置爲unread,即將r向前移動一位。UnreadByte只能在Read或ReadByte操作後執行
func (b *Reader) ReadRune() (r rune, size int, err error) // 讀取一個rune
func (b *Reader) UnreadRune() error //將上一個讀取的rune置爲unread,即將r向前移動一個rune字節數的位置(一般爲1和3)
func (b *Reader) Buffered() int // 返回未讀字節數,即r和w之間的距離
func (b *Reader) ReadSlice(delim byte) (line []byte, err error) // 讀取一個切片,這個切片的最後一個字節是delim
func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error) //讀取一行,相當於ReadSlice('\n'),但是此函數會處理掉行末的'\r'和'\n'
func (b *Reader) ReadBytes(delim byte) ([]byte, error) // 讀取delim及其之前的所有未讀字節。實現是調用了ReadSlice,但是如果在調用ReadSlice時,ReadSlice返回非“緩存區滿”的錯誤,就將一直調用ReadSlice讀下去
func (b *Reader) ReadString(delim byte) (string, error) //調用ReadBytes讀取數據,然後轉換爲字符串
func (b *Reader) WriteTo(w io.Writer) (n int64, err error) // 將buf中的數據寫入到io.Writer中去

Writer

// Writer implements buffering for an io.Writer object.
// If an error occurs writing to a Writer, no more data will be
// accepted and all subsequent writes, and Flush, will return the error.
// After all data has been written, the client should call the
// Flush method to guarantee all data has been forwarded to
// the underlying io.Writer.
type Writer struct {
    err error
    buf []byte
    n int         // 緩存的數據字節數
    wr io.Writer
}

Writer的作用是爲io.Writer提供一個Buffer。
和Reader類似,Go提供兩個Writer的構造函數

func NewWriterSize(w io.Writer, size int) *Writer
func NewWriter(w io.Writer) *Writer              // 相當於NewWriterSize(w, 4096)

func NewWriterSize(w io.Writer, size int) *Writer
如果w本身就是Writer實例,並且len(w.buf) >= size, 則直接將w轉換爲Write類型後返回
如果size <= 0, 設置size爲4096

其他操作函數如下:

func (b *Writer) Size() int
func (b *Writer) Reset(w io.Writer)
func (b *Writer) Flush() error      // 將所有數據寫入到io.Writer中, n置爲0
func (b *Writer) Available() int    // 返回剩餘緩存空間字節數
func (b *Writer) Buffered() int     // 返回緩存的字節數
func (b *Writer) Write(p []byte) (nn int, err error)  // 將p複製到buf中。如果p比剩餘緩存區大,則直接將p寫入到io.Writer中(buf也會被Flush),直到p中剩餘數據比buf剩餘緩存區小後將p剩餘數據複製到buf中
func (b *Writer) WriteByte(c byte) error // 寫入一個字節,如果緩存區已滿,則Flush後再寫入
func (b *Writer) WriteRune(r rune) (size int, err error)
func (b *Writer) WriteString(s string) (int, error) // 寫入字符串
func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) // 從io.Reader中讀取數據到buf中,如果buf讀滿了,Flush

ReadWriter

// ReadWriter stores pointers to a Reader and a Writer.
// It implements io.ReadWriter.
type ReadWriter struct {
    *Reader
    *Writer
}

// NewReadWriter allocates a new ReadWriter that dispatches to r and w.
func NewReadWriter(r *Reader, w *Writer) *ReadWriter {
    return &ReadWriter{r, w}
}

Scanner

// Scanner provides a convenient interface for reading data such as
// a file of newline-delimited lines of text. Successive calls to
// the Scan method will step through the 'tokens' of a file, skipping
// the bytes between the tokens. The specification of a token is
// defined by a split function of type SplitFunc; the default split
// function breaks the input into lines with line termination stripped. Split
// functions are defined in this package for scanning a file into
// lines, bytes, UTF-8-encoded runes, and space-delimited words. The
// client may instead provide a custom split function.
//
// Scanning stops unrecoverably at EOF, the first I/O error, or a token too
// large to fit in the buffer. When a scan stops, the reader may have
// advanced arbitrarily far past the last token. Programs that need more
// control over error handling or large tokens, or must run sequential scans
// on a reader, should use bufio.Reader instead.
//
type Scanner struct {
    r io.Reader // The reader provided by the client.
    split SplitFunc // The function to split the tokens.
    maxTokenSize int // Maximum size of a token; modified by tests.
    token []byte // Last token returned by split.
    buf []byte // Buffer used as argument to split.
    start int // First non-processed byte in buf.
    end int // End of data in buf.
    err error // Sticky error.
    empties int // Count of successive empty tokens.
    scanCalled bool // Scan has been called; buffer is in use.
    done bool // Scan has finished.
}

Scanner的主要作用就是從文件讀取數據
Scanner的具體操作方法如下:

func NewScanner(r io.Reader) *Scanner  // 構造函數
func (s *Scanner) Err() error // 返回任意非io.EOF的錯誤
func (s *Scanner) Bytes() []byte // 返回token中的所有字節
func (s *Scanner) Text() string // 相當於string(Bytes())
func (s *Scanner) Scan() bool // 判斷是否有數據可以讀取
func (s *Scanner) Buffer(buf []byte, max int) // 將s.buf中的數據寫入到buf中
func (s *Scanner) Split(split SplitFunc) //設置拆分函數 s.split = split
func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error) //獲取一個字節作爲一個token
func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error) //獲取一個rune作爲一個token
func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error) //Scanner的默認拆分函數,獲取一行(刪除了\r\n)作爲一個token
func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error) //按照空白字符拆分,取一串非空字符串作爲一個token
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章