bufio 在读写文件时提供了缓存,先将要读取或写入的内容放到缓存中
read
func bufIoRead() {
file := "./test-file"
fd, err := os.Open(file)
if err != nil {
panic(err)
}
defer fd.Close()
// 初始化一个缓冲区大小为100byte的对象
b := bufio.NewReaderSize(fd, 100)
ctx := make([]byte, 30)
var buf bytes.Buffer
fmt.Println("b size is: ", b.Size())
// 将b中的缓存数据读入ctx中
// 如果缓存不为空,则只能读出缓冲中的数据,不会从底层io.Reader中提取数据,如果缓存为空,则:
// 1、len(ctx) >= 缓存大小,则跳过缓存,直接从底层io.Reader中读出到p中
// 2、len(ctx)< 缓存大小,则先将数据从底层io.Reader中读取到缓存中,再从缓存读取到p中。
// 从缓存中读取出的数据将不会再存在与缓存中
if _, err := b.Read(ctx); err != nil {
panic(err)
}
buf.Write(ctx)
fmt.Println(buf.String())
// b.Buffered()返回未被读取的缓存大小
fmt.Println("剩余缓冲大小: ", b.Buffered())
_, err = b.Read(ctx)
if err != nil {
panic(err)
}
buf.Write(ctx)
fmt.Println(buf.String())
fmt.Println("剩余缓冲大小: ", b.Buffered())
}
write
func bufIoWrite() {
file := "./test-file"
fd, err := os.OpenFile(file, os.O_RDWR, os.ModeAppend)
if err != nil {
panic(err)
}
defer fd.Close()
cacheSize := 10
b := bufio.NewWriterSize(fd, cacheSize)
txt := []byte("world ")
// 1、len(txt) + 已缓存大小 > cacheSize,则跳过缓存,直接向底层io.Writer中写入缓存中的数据,注意:超出缓存的部分不会写入
// 2、len(ctx) + 已缓存大小 <= 缓存大小,则先将数据放到缓存中,调用flush后才会写入底层io.Writer
if _, err := b.Write(txt); err != nil {
panic(err)
}
cxt := make([]byte, 100)
if _, err := fd.Read(cxt); err != nil {
if err == io.EOF {
fmt.Println("file is empty.")
} else {
panic(err)
}
}
fmt.Println("before flush cache: ", string(cxt))
fmt.Println("number of bytes that have been written into cache: ", b.Buffered())
fmt.Println("how many bytes are unused in the cache: ", b.Available())
// flush 将缓存中的数据写入到io.Writer
if err := b.Flush(); err != nil {
panic(err)
}
fmt.Println("after flush, number of bytes that have been written into cache: ", b.Buffered())
fmt.Println("after flush, number of bytes are unused in the cache: ", b.Available())
// os.OpenFile适合写入文件时使用,如果读取的话需要设置偏移量,使用ReadAt()
// fd.ReadAt(cxt, 0) 从文件开头读取内容到cxt
if _, err := fd.ReadAt(cxt, 0); err != nil {
if err == io.EOF {
fmt.Println("file is empty.")
} else {
panic(err)
}
}
fmt.Println("after flush cache: ", string(cxt))
file = "./test-file"
fd1, err := os.Open(file)
if err != nil {
panic(err)
}
defer fd1.Close()
b = bufio.NewWriterSize(fd, cacheSize)
// readFrom 从别的文件中读取所有内容并写入到此文件,并不受b的缓存大小限制,且无需调用flush
if _, err := b.ReadFrom(fd1); err != nil {
panic(err)
}
}