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