bufio的地址:https://pkg.go.dev/bufio
bufio的作用: bufio实现了缓冲I/O。它包装了io.Reader或io.Writer对象,创建了另外一个实现了接口但是提供了缓冲和对文本I/O有帮助的对象(Reader或Writer)。
常用:
1.type Writer
Writer对于一个io.Writer对象实现缓冲。如果向一个Writer内写入时遇到错误时,不会再有更多的数据被接受以及后续的写进以及Flush,它会返回错误。当所有的数据被写进,调用者应该调用Flush方法,以保证所有的数据被转发到内置的io.Writer。
Writer的方法:
(1)bufio.NewWriter()
函数:func NewWriter(w io.Writer) *Writer
NewWriter返回一个新的Writer,这个Writer的缓冲器有默认的大小。如果参数io.Writer已经是一个具有足够大缓冲的Writer,它将会返回潜在的Writer。
(2)bufio.NewWriterSize()
函数:func NewWriterSize(w io.Writer, size int) *Writer
NewWriteSize返回一个新的Writer,这个Writer的缓冲器至少有特定的大小。如果参数io.Writer已经是一个具有足够大缓冲的Writer,它将会返回潜在的Writer。
(3)writer.Write()
方法:func (b *Writer) Write(p []byte) (nn int, err error)
Write将p的内容写进缓冲器。它返回已写的字节数量。如果nn < len(p),它将会返回一个错误来解释为什么它写得这么短。
(4)write.WriteByte()
方法:func (b *Writer) WriteByte(c byte) error
WriteByte写进单个字节。
(5)write.WriteRune()
方法:func (b *Writer) WriteRune(r rune) (size int, err error)
WriteRune写进单个Unicode码点,并返回已写的字节数以及任何错误。
插入知识点:byte vs rune(byte表示一个字节,rune代表四个字节)

(6)write.WriteString()
方法:func (b *Writer) WriteString(s string) (int, error)
WriteString写进一个字符。它返回已写的字节数。如果已写字节数 < len(s),它会返回一个错误来解释为什么写得这么短。
(7)write.Flush()
方法:func (b *Writer) Flush() error
Flush将任何已缓冲的数据写进潜在的io.Writer
2.type Reader
(1)bufio.NewReader
函数:func NewReader(rd io.Reader) *Reader
NewReader返回一个新的Reader,这个Reader的缓冲有默认的大小
(2)bufio.NewReaderSize
函数:func NewReaderSize(rd io.Reader, size int) *Reader
NewReaderSize返回一个新的并具有至少的特定大小的缓冲的Reader。如果参数io.Reader是已经有足够大尺寸的Reader,它将会返回潜在的Reader。
(3)reader.Read()
方法:func (b *Reader) Read(p []byte) (n int, err error)
Read读取数据到p中。它返回读取到p中的字节数。字节最多是从一个Read(基于潜在的Reader),因此 n 有可能小于 len(p)。如果要准确地读取 len(n)字节,使用io.ReadFull(b, p)。如果潜在的Reader可以返回一个non-zero数,以及io.EOF, 然后这个Read方法也可以这样做。
(4)reader.ReadByte()
方法:func (b *Reader) ReadByte() (byte, error)
ReadByte读取并返回单个字节,如果没有可获取的字节,则返回error
(5)reader.ReadBytes()
方法:func (b *Reader) ReadBytes(delim byte) ([]byte, error)
ReadBytes读取直到在输入中遇到delim(终结符),返回一个包括到当前数据为止以及包括delimiter(终结符)的切片。如果ReadBytes在找到delimiter之前遇到一个error,它会返回返回在error之前读取的数据以及error本身(通常是io.EOF)。当且仅当在返回的数据中没有在delim处停止时,ReadBytes会返回不等于nil的err。对于简单的使用,Scanner可能会更方便。
(6)reader.ReadLine()
方法:func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error)
ReadLine 是一个级别更低的原始的行读取。大多数的调用者会使用ReadBytes('\n') 或者 ReadString('\n'),再或者使用一个Scanner。
(7)reader.ReadRune()
方法:func (b *Reader) ReadRune() (r rune, size int, err error)
ReadRune 读取单个UTF-8编码的Unicode字符,并且返回rune和它在字节中的大小。如果编码的rune是无效的,它消耗一个字节并且返回unicode.ReplacementChar(U+FFFD) + 大小为1的size
(8)reader.ReadSlice()
方法:func (b *Reader) ReadSlice(delim byte) (line []byte, err error)
ReadSlice读取直到在输入中第一次出现delim(终结符),并返回一个指向缓冲中字节的切片。这字节将在下次读取时无效。 如果ReadSlice在找到delimiter之前遇到一个错误,它会返回缓冲中的所有数据以及错误本身(通常是io.EOF)。如果缓冲填满而无delim,ReadSlice会以错误ErrBufferFull。因为从ReadSlice中返回的数据将会被下次I/O操作重写,大多数的调用者(clients)应该使用ReadBytes 或 ReadString代替。ReadSlice当且仅当行没有以delim结束时,会返回一个不为nil的err。
(9)reader.ReadString()
方法:func (b *Reader) ReadString(delim byte) (string, error)
ReadString读取直到在输入中第一次遇见delim,并且返回一个包含当前数据以及delimiter的字符串。如果ReadString在找到delimiter之前遇到一个错误,它会返回在错误前读取的数据以及错误本身(通常是io.EOF)。ReadString当前仅当返回的数据不是以delim结束时,会返回一个不为nil的err。对于简单的使用,Scanner可能会更方便。
3.type Scanner
参考文章:深入介绍golang中的bufio.Scanner
Scanner提供了一个方便读取像由换行符分隔的文本组成的文件的接口。依次调用Scan方法会步进一个文件的"tokens",跳过tokens之间的字节。token的规范是由SplitFunc类型的split方法来定义的;默认的split方法将输入打破成带有行终端剥离的行。在Scanner包中定义的Split方法用来将一个文件扫描成行/字节/UTF-8编码的runes/空格分隔的words。调用者(client)也许会提供通用的split函数。
在EOF, 第一个I/O错误,或token太大而放不下缓冲,扫描将不可恢复地停止。当一个扫描停止时,reader可能会任意的超出下一个token。对于某些程序,例如需要更多的控制错误处理,或大的tokens,或必须在一个reader中连续运行scans,应该使用bufio.Reader来替代。
(1)bufio.NewScanner()
方法:func NewScanner(r io.Reader) *Scanner
NewScanner返回一个新的Scanner来从r中读取。默认的split函数为ScanLines。
(2)scanner.Scan()
方法:func (s *Scanner) Scan() bool
Scan使Scanner前进到下一个token, 然后这个token将会对于Bytes或Text方法可获得。当扫描停止时,即无论是到达输入的结尾或遇到错误时,将会返回一个false。在Scan返回false,Err方法将会返回任何在扫描中发生的错误, 除非这个错误是io.EOF, Err会返回nil。如果split返回太多空的tokens而没有在input中前进,则Scan panics 。这个是常规的scanners的error模型。
(3)scanner.Text()
方法:func (s *Scanner) Text() string
Text返回最近由调用产生的token,这个调用是调用Scan作为新分配的string来容纳它的bytes。
(4)scanner.Split()
方法:func (s *Scanner) Split(split SplitFunc)
Split为Scanner设置split函数。默认的split函数为ScanLines。
如果split在扫描开始后调用,则Split panics。
(5)bufio.SplitFunc()
方法:type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error)
SplitFunc 是split函数的签名,split函数是用来将输入token化的。
明天继续整理一下:https://pkg.go.dev/bufio#NewScanner