缓存功能
[bufio]
:producer --> buffer --> io.Writer
[Reader]
[Writer]
:bufio.Writer 底层使用 []byte 进行缓存
:bufio.Writer 默认使用 4096 长度字节的缓存,可以使用 NewWriterSize 方法来设定该值
[Scanner]
[重置]
:Reset
[缓存剩余空间]
:Available
package main
import (
"bufio"
"fmt"
)
type Writer int
func (*Writer) Write(p []byte) (n int, err error) {
fmt.Println(len(p))
return len(p), nil
}
func main() {
// 没有被缓存的 I/O,意味着每一次写操作都将直接写入目的地
// 我们进行4次写操作,每次写操作都映射为对 Write 的调用,调用时传入的参数为一个长度为1的 byte 切片
fmt.Println("Unbuffered I/O")
w := new(Writer)
w.Write([]byte{'a'})
w.Write([]byte{'b'})
w.Write([]byte{'c'})
w.Write([]byte{'d'})
// 使用缓存的I/O,使用三个字节长度的缓存来存储数据,当缓存满时进行一次 flush 操作(数据处理)
// 前三次写入写满了缓存,第四次写入时检测到缓存没有剩余空间,所以将缓存中的积累的数据写出
// 字母 d 被存储了,但在此之前 Flush 被调用以腾出空间,当缓存被写到末尾时,缓存中未被处理的数据需要被处理
// bufio.Writer 仅在缓存充满或者显式调用 Flush 方法时处理(发送)数据。
fmt.Println("Buffered I/O")
bw := bufio.NewWriterSize(w, 3)
bw.Write([]byte{'a'})
bw.Write([]byte{'b'})
bw.Write([]byte{'c'})
bw.Write([]byte{'d'})
err := bw.Flush()
if err != nil {
panic(err)
}
}
// 实现原理
type Writer struct {
err error
buf []byte
n int
wr io.Writer
}
// 字段 buf 用来存储数据,当缓存满或者 Flush 被调用时,消费者(wr)可以从缓存中获取到数据。
// 如果写入过程中发生了 I/O error,此 error 将会被赋给 err 字段,error 发生之后,writer 将停止操作
type Writer int
func (*Writer) Write(p []byte) (n int, err error) {
fmt.Printf("Write: %q\n", p)
return 0, errors.New("boom!")
}
func main() {
w := new(Writer)
bw := bufio.NewWriterSize(w, 3)
bw.Write([]byte{'a'})
bw.Write([]byte{'b'})
bw.Write([]byte{'c'})
bw.Write([]byte{'d'})
err := bw.Flush()
fmt.Println(err)
}