目录
bufio 包介绍
bufio包实现了有缓冲的I/O。它包装一个io.Reader或io.Writer接口对象,创建另一个也实现了该接口,且同时还提供了缓冲和一些文本I/O的帮助函数的对象。
golang bufio
bufio
WriteBufferSizeTransport.dialConn
tr := &http.Transport{ WriteBufferSize: 64 * 1024, }
pconn.br = bufio.NewReaderSize(pconn, t.readBufferSize()) pconn.bw = bufio.NewWriterSize(persistConnWriter{pconn}, t.writeBufferSize())
使用bufio进行写
bufio.NewWriterWriterbufio.NewWriterSizeWriter
Writerbufnwr
type Writer struct { err error buf []byte n int wr io.Writer }
bufio.Writer
- 缓存中满数据
- 缓存中仍有空间
- 待写入的数据大于缓存的大小
缓存中满数据
当缓存中满数据时,会执行写操作。
缓存中仍有空间
Flush()
待写入的数据大于缓存的大小
由于此时缓存无法缓存足够的数据,此时会跳过缓存直接执行写操作
type Writer int func (*Writer) Write(p []byte) (n int, err error) { fmt.Printf("Writing: %s\n", p) return len(p), nil } func main() { w := new(Writer) bw1 := bufio.NewWriterSize(w, 4) // Case 1: Writing to buffer until full bw1.Write([]byte{'1'}) bw1.Write([]byte{'2'}) bw1.Write([]byte{'3'}) bw1.Write([]byte{'4'}) // write - buffer is full // Case 2: Buffer has space bw1.Write([]byte{'5'}) //此时buffer中无法容纳更多的数据,执行写操作,写入 []byte{'1','2','3','4'} err = bw1.Flush() // forcefully write remaining if err != nil { panic(err) } // Case 3: (too) large write for buffer // Will skip buffer and write directly bw1.Write([]byte("12345")) //buffer不足,直接执行写操作 //结果: Writing: 1234 Writing: 5 Writing: 12345
缓存重用
ResetWritern
wr := new(Writer) bw := bufio.NewWriterSize(wr,2) bw.Reset(wr)
获取缓存的可用空间数
Available()len(Writer.buf)-Writer.n
使用bufio进行读
WriterReaderNewReaderReaderNewReaderSizeReaderReaderr
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 }
Peek
该方法会返回buf中的前n个字节的内容,但与Read操作不同的是,它不会消费缓存中的数据,即不会增加数据偏移量,因此通常也会用于判断是否读取结束(EOF)。通常有如下几种情况:
- 如果peak的值小于缓存大小,则返回相应的内容
- 如果peak的值大于缓存大小,则返回bufio.ErrBufferFull错误
- 如果peak的值包含EOF且小于缓存大小,则返回EOF
Read
pp
func (b *Reader) Read(p []byte) (n int, err error)
ReadSlice
delimdelimio.ErrBufferFull
func (b *Reader) ReadSlice(delim byte) (line []byte, err error)
delim','1234,
r := strings.NewReader("1234,567") rb := bufio.NewReaderSize(r, 20) fmt.Println(rb.ReadSlice(',')) // 结果:[49 50 51 52 44] <nil>
// Because the data returned from ReadSlice will be overwritten // by the next I/O operation, most clients should use // ReadBytes or ReadString instead.
ReadLine
ReadLine() (line []byte, isPrefix bool, err error)
ReadLineReadSlice\n\r\nio.ErrBufferFullisPrefixtrue
ReadBytes
ReadSlicedelimReadBytesio.EOF
func (b *Reader) ReadBytes(delim byte) ([]byte, error)
Scanner
scanner可以不断将数据读取到缓存(默认64*1024字节)。
rb := strings.NewReader("12345678901234567890") scanner := bufio.NewScanner(rb) for scanner.Scan() { fmt.Printf("Token (Scanner): %q\n", scanner.Text()) } // 结果:Token (Scanner): "12345678901234567890"
参考
您可能感兴趣的文章: