?
本文檔使用 php中文網(wǎng)手冊 發(fā)布
import "bufio"
概述
索引
示例
軟件包 bufio 實現(xiàn)了緩沖 I/O 。它包裝一個 io.Reader 或io.Writer 對象,創(chuàng)建另一個對象(Reader 或 Writer),它也實現(xiàn)了接口,但提供緩沖和文本 I/O 的一些幫助。
Contants(常量)
Variables(變量)
func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error)
func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error)
func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error)
func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error)
type ReadWriter
func NewReadWriter(r *Reader, w *Writer) *ReadWriter
type Reader
func NewReader(rd io.Reader) *Reader
func NewReaderSize(rd io.Reader, size int) *Reader
func (b *Reader) Buffered() int
func (b *Reader) Discard(n int) (discarded int, err error)
func (b *Reader) Peek(n int) ([]byte, error)
func (b *Reader) Read(p []byte) (n int, err error)
func (b *Reader) ReadByte() (byte, error)
func (b *Reader) ReadBytes(delim byte) ([]byte, error)
func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error)
func (b *Reader) ReadRune() (r rune, size int, err error)
func (b *Reader) ReadSlice(delim byte) (line []byte, err error)
func (b *Reader) ReadString(delim byte) (string, error)
func (b *Reader) Reset(r io.Reader)
func (b *Reader) UnreadByte() error
func (b *Reader) UnreadRune() error
func (b *Reader) WriteTo(w io.Writer) (n int64, err error)
type Scanner
func NewScanner(r io.Reader) *Scanner
func (s *Scanner) Buffer(buf []byte, max int)
func (s *Scanner) Bytes() []byte
func (s *Scanner) Err() error
func (s *Scanner) Scan() bool
func (s *Scanner) Split(split SplitFunc)
func (s *Scanner) Text() string
type SplitFunc
type Writer
func NewWriter(w io.Writer) *Writer
func NewWriterSize(w io.Writer, size int) *Writer
func (b *Writer) Available() int
func (b *Writer) Buffered() int
func (b *Writer) Flush() error
func (b *Writer) ReadFrom(r io.Reader) (n int64, err error)
func (b *Writer) Reset(w io.Writer)
func (b *Writer) Write(p []byte) (nn int, err error)
func (b *Writer) WriteByte(c byte) error
func (b *Writer) WriteRune(r rune) (size int, err error)
func (b *Writer) WriteString(s string) (int, error)
Scanner (Custom) Scanner (EmptyFinalToken) Scanner (Lines) Scanner (Words) Writer
bufio.go scan.go
const ( // MaxScanTokenSize是用于緩沖令牌的最大大小 // 除非用戶使用Scan.Buffer提供一個明確的緩沖區(qū)。 // 緩沖區(qū)的實際最大標記大小可能較小 // 可能需要包含一個換行符。 MaxScanTokenSize = 64 * 1024)
var ( ErrInvalidUnreadByte = errors.New("bufio: invalid use of UnreadByte") ErrInvalidUnreadRune = errors.New("bufio: invalid use of UnreadRune") ErrBufferFull = errors.New("bufio: buffer full") ErrNegativeCount = errors.New("bufio: negative count"))
Scanner 返回的錯誤。
var ( ErrTooLong = errors.New("bufio.Scanner: token too long") ErrNegativeAdvance = errors.New("bufio.Scanner: SplitFunc returns negative advance count") ErrAdvanceTooFar = errors.New("bufio.Scanner: SplitFunc returns advance count beyond input"))
ErrFinalToken 是一個特殊的 sentinel 錯誤值。它旨在通過 Split 函數(shù)返回,以指示隨錯誤交付的令牌是最后一個令牌,并且在此之后應該停止掃描。掃描收到 ErrFinalToken 后,掃描停止,沒有錯誤。該值對于提前停止處理或需要傳遞最終空令牌時非常有用??梢杂米远x的錯誤值實現(xiàn)相同的行為,但是在這里提供一個更整齊。查看 emptyFinalToken 示例以了解該值的用法。
var ErrFinalToken = errors.New("final token")
func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error)
ScanBytes 是 Scanner 的分割函數(shù),它將每個字節(jié)作為標記返回。
func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error)
ScanLines 是掃描儀的分離功能,可以返回每一行文本,并將任何尾隨行尾標記剝離。返回的行可能為空。行尾標記是一個可選的回車符,后跟一個強制換行符。在正則表達式中,它是\r?\n
。即使沒有換行,也會返回最后一個非空行輸入。
func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error)
ScanRunes 是掃描儀的分離功能,可以將每個UTF-8編碼符文作為標記返回。返回的符文序列與輸入中的范圍循環(huán)相當于一個字符串,這意味著錯誤的UTF-8編碼轉換為 U+FFFD = "\xef\xbf\xbd"。由于Scan界面,這使得客戶端無法區(qū)分正確編碼的替換符文和編碼錯誤。
func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error)
ScanWords 是 Scanner 的分割功能,可以返回每個空格分隔的文字,并刪除周圍的空格。它永遠不會返回一個空字符串??臻g的定義由 unicode.IsSpace 設置。
ReadWriter 存儲指向 Reader 和 Writer 的指針。它實現(xiàn)了io.ReadWriter。
type ReadWriter struct { *Reader *Writer}
func NewReadWriter(r *Reader, w *Writer) *ReadWriter
NewReadWriter 分配一個新的 ReadWriter 分派給 r 和 w 。
Reader 為 io.Reader 對象實現(xiàn)緩沖。
type Reader struct { // 包含過濾或未導出的字段}
func NewReader(rd io.Reader) *Reader
NewReader 返回一個新的 Reader ,其緩沖區(qū)具有默認大小。
func NewReaderSize(rd io.Reader, size int) *Reader
NewReaderSize 返回一個新的 Reader,其緩沖區(qū)至少具有指定的大小。如果參數(shù) io.Reader 已經(jīng)是一個足夠大的 Reader ,它將返回底層的 Reader。
func (b *Reader) Buffered() int
Buffered 返回可以從當前緩沖區(qū)讀取的字節(jié)數(shù)。
func (b *Reader) Discard(n int) (discarded int, err error)
丟棄跳過下 n 個字節(jié),返回丟棄的字節(jié)數(shù)。
如果放棄跳過少于 n 個字節(jié),它也會返回一個錯誤。如果 0 <= n <= b.Buffered(),則 Discard 保證在不讀取底層 io.Reader 的情況下成功。
func (b *Reader) Peek(n int) ([]byte, error)
Peek 返回接下來的n個字節(jié),而不會推進閱讀器。字節(jié)在下次讀取呼叫時停止有效。如果 Peek 返回少于 n 個字節(jié),它也會返回一個錯誤,解釋為什么讀取很短。如果 n 大于 b 的緩沖區(qū)大小,則錯誤為 ErrBufferFull。
func (b *Reader) Read(p []byte) (n int, err error)
讀取數(shù)據(jù)到頁面。它返回讀入p的字節(jié)數(shù)。這些字節(jié)是從底層讀取器讀取的,因此 n 可能小于 len(p) 。在 EOF 時,計數(shù)將為零,err 將為 io.EOF 。
func (b *Reader) ReadByte() (byte, error)
ReadByte 讀取并返回一個字節(jié)。如果沒有可用的字節(jié),則返回錯誤。
func (b *Reader) ReadBytes(delim byte) ([]byte, error)
ReadBytes 讀取直到輸入中第一次出現(xiàn) delim ,并返回一個包含數(shù)據(jù)的片段直至并包含分隔符。如果 ReadBytes 在查找分隔符之前遇到錯誤,它將返回錯誤之前讀取的數(shù)據(jù)和錯誤本身(通常為io.EOF )。當且僅當返回的數(shù)據(jù)不以分隔符結束時,ReadBytes 返回 err != nil 。對于簡單的用途,掃描儀可能更方便。
func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error)
ReadLine 是一個低級的 line-reading 取原語。大多數(shù)調用者應該使用 ReadBytes('\n') 或 ReadString('\n') 來代替或使用掃描器。
ReadLine 嘗試返回一行,不包括行尾字節(jié)。如果該行對于緩沖區(qū)太長,則設置 isPrefix 并返回該行的開頭。該行的其余部分將從未來的調用中返回。返回該行的最后一個片段時,isPrefix 將為false。返回的緩沖區(qū)僅在下一次調用 ReadLine 之前有效。ReadLine 也可以返回一個非零行,或者返回一個錯誤,從來不是兩者一起。
從 ReadLine 返回的文本不包含行尾("\r\n" 或 "\n")。如果輸入沒有最后一行結束,則沒有提示或錯誤。在 ReadLine 之后調用 UnreadByte 將始終讀取最后讀取的字節(jié)(可能是屬于行結束的字符),即使該字節(jié)不是由 ReadLine 返回的行的一部分。
func (b *Reader) ReadRune() (r rune, size int, err error)
ReadRune 讀取單個 UTF-8 編碼的 Unicode 字符,并以字節(jié)為單位返回符文及其大小。如果編碼的符文無效,它將消耗一個字節(jié)并返回大小為1的 unicode.ReplacementChar (U+FFFD)。
func (b *Reader) ReadSlice(delim byte) (line []byte, err error)
ReadSlice 讀取直到輸入中第一次出現(xiàn) delim,返回指向緩沖區(qū)中字節(jié)的片段。字節(jié)在下次讀取時停止有效。如果ReadSlice在查找分隔符之前遇到錯誤,它將返回緩沖區(qū)中的所有數(shù)據(jù)和錯誤本身(通常為 io.EOF)。如果緩沖區(qū)沒有分隔符,則ReadSlice將失敗并返回錯誤 ErrBufferFull 。因為從 ReadSlice 返回的數(shù)據(jù)將被下一個I/O操作覆蓋,所以大多數(shù)客戶端應該使用ReadBytes 或ReadString。ReadSlice 返回 err != nil 當且僅當該行不以 delim結束時。
func (b *Reader) ReadString(delim byte) (string, error)
ReadString 進行讀取,直到輸入中第一次出現(xiàn) delim,返回一個包含數(shù)據(jù)的字符串直到并包含分隔符。如果 ReadString 在查找分隔符之前遇到錯誤,它將返回在錯誤之前讀取的數(shù)據(jù)和錯誤本身(通常為 io.EOF)。當且僅當返回的數(shù)據(jù)沒有以分隔符結束時,ReadString 返回 err != nil。對于簡單的用途,掃描儀可能更方便。
func (b *Reader) Reset(r io.Reader)
重置放棄任何緩沖數(shù)據(jù),重置所有狀態(tài),并將緩沖讀取器從 r 讀取。
func (b *Reader) UnreadByte() error
UnreadByte 未讀取最后一個字節(jié)。只有最近讀取的字節(jié)可以是未讀的。
func (b *Reader) UnreadRune() error
UnreadRune 未閱讀最后的符文。如果緩沖區(qū)上的最新讀取操作不是 ReadRune,則 UnreadRune 會返回錯誤。(在這方面,它比 UnreadByte 更嚴格,它將讀取任何讀操作的最后一個字節(jié)。)
func (b *Reader) WriteTo(w io.Writer) (n int64, err error)
WriteTo 實現(xiàn) io.WriterTo。這可能會多次調用底層 Reader 的Read 方法。
Scanner 為閱讀數(shù)據(jù)提供了一個方便的界面,例如文本換行符分隔的文本。連續(xù)調用 Scan 方法將跳過文件的“令牌”,跳過令牌之間的字節(jié)。令牌的規(guī)范由 SplitFunc 類型的分割函數(shù)定義;默認的分割功能將輸入分割為行終止的行。在此包中定義了分割函數(shù),用于將文件掃描為行,字節(jié),UTF-8 編碼的符文和空格分隔的文字??蛻舳丝梢愿臑樘峁┳远x分割功能。
掃描在 EOF 處無法恢復,第一個 I/O 錯誤或太大而無法放入緩沖區(qū)的令牌。當掃描停止時,讀者可能已經(jīng)遠離最后一個標記任意地前進了。需要對錯誤處理或大標記進行更多控制的程序,或者必須在閱讀器上運行順序掃描的程序應改為使用 bufio.Reader。
type Scanner struct { // 包含過濾或未導出的字段}
使用具有自定義拆分功能的 Scanner(通過封裝 ScanWords 構建)來驗證32位十進制輸入。
代碼:
// 人為輸入源。const input = "1234 5678 1234567901234567890"scanner := bufio.NewScanner(strings.NewReader(input))// 通過包裝現(xiàn)有的ScanWords函數(shù)來創(chuàng)建自定義拆分功能。split := func(data []byte, atEOF bool) (advance int, token []byte, err error) { advance, token, err = bufio.ScanWords(data, atEOF) if err == nil && token != nil { _, err = strconv.ParseInt(string(token), 10, 32) } return}// 設置掃描操作的分割功能。scanner.Split(split)// 驗證輸入for scanner.Scan() { fmt.Printf("%s\n", scanner.Text())}if err := scanner.Err(); err != nil { fmt.Printf("Invalid input: %s", err)}
輸出:
12345678Invalid input: strconv.ParseInt: parsing "1234567901234567890": value out of range
使用具有自定義拆分功能的掃描儀可以用空的最終值分析逗號分隔的列表。
package mainimport ("bufio""fmt""os""strings")func main() {// 逗號分隔的列表; 最后一項是空的。const input = "1,2,3,4," scanner := bufio.NewScanner(strings.NewReader(input))// 定義一個以逗號分隔的分割函數(shù)。 onComma := func(data []byte, atEOF bool) (advance int, token []byte, err error) {for i := 0; i < len(data); i++ {if data[i] == ',' {return i + 1, data[:i], nil}}// 有一個最終的令牌要交付,可能是空字符串。// 在這里返回bufio.ErrFinalToken告訴Scan,在此之后沒有更多的標記// 但不會觸發(fā)從掃描本身返回的錯誤。return 0, data, bufio.ErrFinalToken} scanner.Split(onComma)// Scan.for scanner.Scan() { fmt.Printf("%q ", scanner.Text())}if err := scanner.Err(); err != nil { fmt.Fprintln(os.Stderr, "reading input:", err)}}
最簡單的 Scanner 使用,可以將標準輸入讀取為一組行。
package mainimport ("bufio""fmt""os")func main() { scanner := bufio.NewScanner(os.Stdin)for scanner.Scan() { fmt.Println(scanner.Text()) // Println將添加最后的'\n'}if err := scanner.Err(); err != nil { fmt.Fprintln(os.Stderr, "reading standard input:", err)}}
使用掃描程序通過將輸入掃描為一系列空格分隔的令牌來實現(xiàn)簡單的字數(shù)統(tǒng)計實用程序。
package mainimport ("bufio""fmt""os""strings")func main() {// 人為輸入源。const input = "Now is the winter of our discontent,\nMade glorious summer by this sun of York.\n" scanner := bufio.NewScanner(strings.NewReader(input))// 設置掃描操作的分割功能。 scanner.Split(bufio.ScanWords)// 計算單詞。 count := 0for scanner.Scan() { count++}if err := scanner.Err(); err != nil { fmt.Fprintln(os.Stderr, "reading input:", err)} fmt.Printf("%d\n", count)}
func NewScanner(r io.Reader) *Scanner
NewScanner 返回一個新的掃描儀來從 r 讀取內容。分割功能默認為 ScanLines。
func (s *Scanner) Buffer(buf []byte, max int)
緩沖區(qū)設置掃描時要使用的初始緩沖區(qū)以及掃描期間可能分配的最大緩沖區(qū)大小。最大令牌大小是 max 和 cap(buf) 中較大的一個。如果 max <= cap(buf),掃描將僅使用此緩沖區(qū)并且不進行分配。
默認情況下,Scan 使用內部緩沖區(qū)并將最大標記大小設置為MaxScanTokenSize 。
如果在掃描開始后調用緩沖區(qū),則會發(fā)生混亂。
func (s *Scanner) Bytes() []byte
字節(jié)返回由掃描調用產(chǎn)生的最新令牌。底層數(shù)組可能指向將被隨后的掃描調用覆蓋的數(shù)據(jù)。它沒有分配。
func (s *Scanner) Err() error
Err 返回掃描器遇到的第一個非EOF錯誤。
func (s *Scanner) Scan() bool
掃描將掃描儀推進到下一個標記,然后通過字節(jié)或文本方法使用該標記。當掃描停止時,它會返回 false,通過到達輸入末尾或錯誤。在 Scan 返回 false 后,Err 方法將返回掃描期間發(fā)生的任何錯誤,除了如果它是 io.EOF,Err 將返回 nil。如果分割函數(shù)返回100個空令牌而不提前輸入,則掃描恐慌。這是掃描儀的常見錯誤模式。
func (s *Scanner) Split(split SplitFunc)
分割設定掃描儀的分割功能。默認的分割功能是 ScanLines 。
如果在掃描開始后調用它,則會將其分割。
func (s *Scanner) Text() string
文本將通過調用 Scan 生成的最新令牌返回為保存其字節(jié)的新分配的字符串。
SplitFunc 是用于標記輸入的分割函數(shù)的簽名。參數(shù)是剩余的未處理數(shù)據(jù)的初始子字符串和 atEOF 標志,該標志報告 Reader 是否沒有更多數(shù)據(jù)可供使用。返回值是提前輸入的字節(jié)數(shù)和返回給用戶的下一個標記,以及一個錯誤(如果有的話)。如果數(shù)據(jù)還沒有保存一個完整的標記,例如在掃描行時沒有換行符,SplitFunc可以返回 (0, nil, nil) 來指示掃描器向切片中讀入更多數(shù)據(jù),并用較長的切片再次嘗試從輸入中的相同點開始。
如果返回的錯誤不為零,則掃描停止并將錯誤返回給客戶端。
除非 atEOF 為真,否則該函數(shù)絕不會用空數(shù)據(jù)切片調用。但是,如果 atEOF 為真,則數(shù)據(jù)可能非空,并且一如既往地保留未處理的文本。
type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error)
編寫器為 io.Writer 對象實現(xiàn)緩沖。如果寫入寫入器時發(fā)生錯誤,則不會接受更多數(shù)據(jù),并且所有后續(xù)寫入和刷新都將返回錯誤。完成所有數(shù)據(jù)寫入后,客戶端應調用 Flush 方法以確保所有數(shù)據(jù)已轉發(fā)到基礎 io.Writer。
type Writer struct { // 包含過濾或未導出的字段}
package mainimport ("bufio""fmt""os")func main() { w := bufio.NewWriter(os.Stdout) fmt.Fprint(w, "Hello, ") fmt.Fprint(w, "world!") w.Flush() // 不要忘記刷新!}
func NewWriter(w io.Writer) *Writer
NewWriter 返回一個新的 Writer,其緩沖區(qū)具有默認大小。
func NewWriterSize(w io.Writer, size int) *Writer
NewWriterSize 返回一個新的 Writer,其緩沖區(qū)至少具有指定的大小。如果參數(shù) io.Writer 已經(jīng)是一個尺寸足夠大的 Writer,它將返回底層的 Writer。
func (b *Writer) Available() int
可用返回緩沖區(qū)中未使用的字節(jié)數(shù)。
func (b *Writer) Buffered() int
Buffered 返回已寫入當前緩沖區(qū)的字節(jié)數(shù)。
func (b *Writer) Flush() error
Flush 將任何緩沖的數(shù)據(jù)寫入底層的 io.Writer。
func (b *Writer) ReadFrom(r io.Reader) (n int64, err error)
ReadFrom 實現(xiàn)了 io.ReaderFrom。
func (b *Writer) Reset(w io.Writer)
重置放棄任何未刷新的緩沖數(shù)據(jù),清除任何錯誤,并重置b以將其輸出寫入 w。
func (b *Writer) Write(p []byte) (nn int, err error)
Write 將 p 的內容寫入緩沖區(qū)。它返回寫入的字節(jié)數(shù)。如果nn < len(p),它也會返回一個錯誤,解釋為什么寫入很短。
func (b *Writer) WriteByte(c byte) error
WriteByte 寫入一個字節(jié)。
func (b *Writer) WriteRune(r rune) (size int, err error)
WriteRune 寫入一個 Unicode 代碼點,返回寫入的字節(jié)數(shù)和任何錯誤。
func (b *Writer) WriteString(s string) (int, error)
WriteString 寫入一個字符串。它返回寫入的字節(jié)數(shù)。如果計數(shù)小于 len(s),它也會返回一個錯誤,解釋為什么寫入很短。