一天一个Golang包,慢慢学习之“bufio”
今天学习带缓存的I/O操作,基础包“bufio”中有bufio.go和scan.go两个文件
阅读文档: 官方pkg地址:https://golang.org/pkg/bufio/
包方法
func NewReadWriter(r *Reader, w *Writer) *ReadWriter // 将r和w封装为一个bufio.Readwriter对象
func NewReader(rd io.Reader) *Reader // 将rd封装为一个bufio.Reader对象(缓存大小默认4096)
func NewReaderSize(rd io.Reader, size int) *Reader // 将rd封装成一个拥有size大小缓存的bufio.Reader对象
func NewScanner(r io.Reader) *Scanner // 创建一个Scanner来扫描r
func NewWriter(w io.Writer) *Writer // 将w封装成一个bufio.Writer对象(缓存大小默认4096)
func NewWriterSize(w io.Writer, size int) *Writer //将w封装成一个拥有size大小缓存的bufio.Writer对象
Reader结构体
1 2 3 4 5 6 7 8 9 type Reader struct { buf []byte rd io.Reader r, w int err error lastByte int lastRuneSize int }
func (b *Reader) Buffered() int // 返回缓存中的数据长度
func (b *Reader) Discard(n int) (discarded int, err error) // 丢弃接下来的n个字节,返回丢弃的字节长度
func (b *Reader) Peek(n int) ([]byte, error) // 返回前n字节的缓存切片
func (b *Reader) Read(p []byte) (n int, err error) // 读取len(p)个字节到p中。 // 如果len(p)>缓存大小,且缓存不为空,则读取全部缓存。 // 若缓存为空,则从底层io.Reader直接读取
func (b *Reader) ReadByte() (byte, error) // 读出一个字节并返回
func (b *Reader) ReadBytes(delim byte) ([]byte, error) // 查找delim并读取delim及其之前的所有数据(byte切片) // 如果在找到delim之前发生错误,则返回发生错误之前的数据和error。 // 当找不到delim的时候,err!=nil
func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error) // 返回一个单行数据(切片),不包括行尾标记。 // 如果在缓存中找不到行尾标记,isPrefix为true,表示查找未完成,否则isPrefix为false
func (b *Reader) ReadRune() (r rune, size int, err error) // 读取一个UTF8字符和字符的编码长度。 // 如果UTF8序列无法解码出一个正确的Unicode字符,则只读出一个字节,并返回U+FFFD字符,size返回1。
func (b *Reader) ReadSlice(delim byte) (line []byte, err error) // 查找delim并读取delim及其之前的所有数据(byte切片-引用)
func (b *Reader) ReadString(delim byte) (string, error) // 查找delim并读取delim及其之前的所有数据(字符串)
func (b *Reader) Reset(r io.Reader) // 丢弃任何缓存数据,重置所有状态并切换io.Reader到r
func (r *Reader) Size() int // 返回(底层)缓存的字节长度
func (b *Reader) UnreadByte() error // 撤销最后一次读出的一个字节
func (b *Reader) UnreadRune() error // 撤销最后一次读出的Unicode字符 // 如果最后一次执行的不是ReadRune(),则返回一个错误
func (b *Reader) WriteTo(w io.Writer) (n int64, err error) // 实现了io.WriteTo接口。 // 可以(可能)对底层Reader的Read方法进行多次调用。 // 如果底层Reader支持WriteTo方法,则直接调用底层方法,无需缓存。
Reader的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 package bufioimport ( "bufio" "bytes" "fmt" ) func Reader () { testB := bytes.NewReader([]byte ("abcdefg\nABCDEFG\nh i j k\nH I J K\n\nline." )) bufRd := bufio.NewReader(testB) fmt.Println(bufRd.Buffered(), bufRd.Size()) b, _ := bufRd.ReadByte() fmt.Println(bufRd.Buffered(), b, string (b)) bs, _ := bufRd.ReadBytes('d' ) fmt.Println(bufRd.Buffered(), bs, string (bs)) discard, _ := bufRd.Discard(1 ) fmt.Println("discard:" , discard, "bufferd:" , bufRd.Buffered()) b, _ = bufRd.ReadByte() fmt.Println(bufRd.Buffered(), b, string (b)) bs, _ = bufRd.Peek(7 ) fmt.Println(bufRd.Buffered(), bs, string (bs)) line, isPrefix, _ := bufRd.ReadLine() fmt.Println(bufRd.Buffered(), line, string (line), isPrefix) r, size, _ := bufRd.ReadRune() fmt.Println(bufRd.Buffered(), r, string (r), size) slice, _ := bufRd.ReadSlice('D' ) fmt.Println(bufRd.Buffered(), slice, string (slice)) str, _ := bufRd.ReadString('G' ) fmt.Println(bufRd.Buffered(), str) bufRd.Reset(bytes.NewReader([]byte ("Hello World.\nMy World." ))) str, _ = bufRd.ReadString('r' ) fmt.Println(bufRd.Buffered(), str) bufRd.UnreadByte() fmt.Println(bufRd.Buffered()) str, _ = bufRd.ReadString('\n' ) fmt.Println(bufRd.Buffered(), str) r, size, _ = bufRd.ReadRune() fmt.Println(bufRd.Buffered(), r, string (r), size) bufRd.UnreadRune() fmt.Println(bufRd.Buffered()) str, _ = bufRd.ReadString('\n' ) fmt.Println(bufRd.Buffered(), str) }
Writer结构体
1 2 3 4 5 6 7 8 9 type Writer struct { err error buf []byte n int wr io.Writer }
func NewWriter(w io.Writer) *Writer // 将w封装成一个bufio.Writer对象,缓存大小为4096.
func NewWriterSize(w io.Writer, size int) *Writer // 将w封装成一个拥有size大小缓存的bufio.Writer对象
func (b *Writer) Available() int // 返回缓存中的可用空间
func (b *Writer) Buffered() int // 返回缓存中未提交的数据长度
func (b *Writer) Flush() error // 将缓存中的数据提交到底层io.Writer中
func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) // 实现了io.ReaderFrom接口。 // 如果底层writer支持ReadFrom方法且b的缓存数据为空,则直接调用底层的ReadFrom方法,不使用缓存。
func (b *Writer) Reset(w io.Writer) // 丢弃所有未被提交的缓存数据,重置所有状态并切换io.Writer到w
func (b *Writer) Size() int // 以字节为单位返回(底层)缓冲区大小
func (b *Writer) Write(p []byte) (nn int, err error) // 将p中的数据写入b中,返回写入的字节数 // 如果写入的字节数小于p的长度,则返回错误
func (b *Writer) WriteByte(c byte) error // 写入一个字节
func (b *Writer) WriteRune(r rune) (size int, err error) // 写入一个UTF8编码字符
func (b *Writer) WriteString(s string) (int, error) // 写入一个字符串,返回写入的字节数
Writer的示列:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 package bufioimport ( "bufio" "bytes" "fmt" ) func Writer () { bt := make ([]byte , 0 ) Bt := bytes.NewBuffer(bt) bufWt := bufio.NewWriter(Bt) fmt.Println(bufWt.Available(), bufWt.Buffered()) nn, _ := bufWt.Write([]byte {65 , 66 }) fmt.Println(bufWt.Available(), bufWt.Buffered()) fmt.Println(nn, Bt) bufWt.Flush() fmt.Println(bufWt.Available(), bufWt.Buffered()) fmt.Println(nn, Bt) bufWt.WriteByte('C' ) fmt.Println(bufWt.Available(), bufWt.Buffered()) fmt.Println(Bt) bufWt.Flush() fmt.Println(bufWt.Available(), bufWt.Buffered()) fmt.Println(Bt) size, _ := bufWt.WriteRune('D' ) fmt.Println(bufWt.Available(), bufWt.Buffered()) fmt.Println(size, Bt) bufWt.Flush() fmt.Println(bufWt.Available(), bufWt.Buffered()) fmt.Println(Bt) n, _ := bufWt.WriteString("EFG" ) fmt.Println(bufWt.Available(), bufWt.Buffered()) fmt.Println(n, Bt) bufWt.Flush() fmt.Println(bufWt.Available(), bufWt.Buffered()) fmt.Println(Bt) fmt.Println(bufWt.Size()) some := bytes.NewReader([]byte ("HIJKLMN" )) nChar, _ := bufWt.ReadFrom(some) fmt.Println(bufWt.Available(), bufWt.Buffered()) fmt.Println(nChar, Bt) bufWt.WriteByte('\n' ) fmt.Println(bufWt.Available(), bufWt.Buffered()) fmt.Println(Bt) some2 := bytes.NewReader([]byte ("OPQRST" )) nChar, _ = bufWt.ReadFrom(some2) fmt.Println(bufWt.Available(), bufWt.Buffered()) fmt.Println(nChar, Bt) bufWt.Flush() fmt.Println(bufWt.Available(), bufWt.Buffered()) fmt.Println(Bt) }
Scanner结构体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 type Scanner struct { r io.Reader split SplitFunc maxTokenSize int token []byte buf []byte start int end int err error empties int scanCalled bool done bool }
func (s *Scanner) Buffer(buf []byte, max int) // 用于设置自定义缓存以及可扩展范围,如果max小于len(buf),则buf的尺寸将固定不可调。 // Buffer必须在第一次Scan之前设置,否则引发Panic。 // 默认情况下,Scanner将会使用一个4096-bufio.MaxScanTokenSize大小的内部缓存。
func (s *Scanner) Bytes() []byte // 将最后一次扫描出的‘指定部分’作为切片(引用)返回 // 下一次的扫描会覆盖本结果
func (s *Scanner) Err() error // 返回扫描过程中遇到的非EOF错误
func (s *Scanner) Scan() bool // 扫描数据中的‘指定部分’
func (s *Scanner) Split(split SplitFunc) // 设置Scanner的分切函数,必须在Scan方法之前调用
func (s *Scanner) Text() string // 最后一次扫描出的‘指定部分’作为String返回
Scanner的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 package bufioimport ( "bufio" "bytes" "fmt" ) func Scan () { b1 := bytes.NewReader([]byte ("ABC\nDEF\r\nGHI\nJKL" )) bs := bufio.NewScanner(b1) for bs.Scan() { fmt.Printf("%s %v\n" , bs.Bytes(), bs.Text()) } b2 := bytes.NewReader([]byte ("ABC\nDEF GHI JKL" )) bs = bufio.NewScanner(b2) bs.Split(bufio.ScanWords) for bs.Scan() { fmt.Println(bs.Text()) } b3 := bytes.NewReader([]byte ("Hello 世界!" )) bs = bufio.NewScanner(b3) bs.Split(bufio.ScanRunes) for bs.Scan() { fmt.Printf("%v " , bs.Text()) } fmt.Println() b4 := bytes.NewReader([]byte ("我的天哪!" )) bs = bufio.NewScanner(b4) bs.Split(bufio.ScanBytes) for bs.Scan() { fmt.Printf("%v " , bs.Bytes()) } fmt.Println() }
另外的参考: