GO标准库巡礼-bufio

本文深入探讨了Go标准库中的bufio包,包括bufio.Writer、Reader、Scanner和ReadWriter的使用。介绍了buffer在提高I/O性能中的作用,缓冲区的管理、错误处理,以及如何进行读写操作。同时,讨论了不同情况下如何处理数据、错误和优化性能,并举例说明了常见功能的实现方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

声明:该系列文章是基于对@golangspec、go官方文档、《Go语言标准库》的学习汇总而成

bufio封装了io.Reader和io.Writer并且通过缓存来提高性能。

bufio.Writer
为什么需要buffer?

在没有buffer的情况下,我们的writer函数会调用系统调用来完成一次写入,而小量写入下,系统调用的时间花销远远大于写入本身的花销。因此,过多的小量写入会大大影响性能。

因此我们可以使用bufio来封装writer,在内部,每次的write会变成写入buffer而不是直接写入磁盘。下面是一个四个字节的buffer的示意,我们可以看到,通过使用buffer,我们将原先需要的9次write调用变为了两次,从而大大提高了性能

producer         buffer           destination (io.Writer)
 
   a    ----->   a
   b    ----->   ab
   c    ----->   abc
   d    ----->   abcd
   e    ----->   e      ------>   abcd
   f    ----->   ef               abcd
   g    ----->   efg              abcd
   h    ----->   efgh             abcd
   i    ----->   i      ------>   abcdefgh
使用bufio.Writer

我们可以通过调用bufio.NewWriter(io.Writer)*Writer来创建有buffer的writer。

在内部,会默认使用4096字节作为buffer,如果希望修改buffer大小可以使用bufio.NewWriterSize(io.Writer,int)*Writer

什么时候实质写入(调用底层writer的Write)

buffer存满或者手动调用Flush()函数的时候,bufio.Writer会调用底层Write写入buffer数据。

如果不自行调用Flush的话,bufio.Writer的buffer中可能会有数据未写入。

什么时候会触发错误?对错误如何处理?

当因为Flush或者buffer已满而调用Write的时候可能会触发错误。一旦某次Write调用触发了错误,再次写入会不执行而直接返回该错误。

当写入大于buffer容量的数据时,bufio.Writer如何处理?

当我们要写入的数据量(或者填满了当前buffer后的剩余数据量)大于buffer容量时候,会直接调用底层Write函数而不是存入buffer

如何获知当前已使用的buffer容量?

可以使用bufio.Writer.Buffered()获取

如何重用buffer避免不必要的内存分配?

我们可以使用bufio.Writer.Reset(io.Writer)来重新设置底层writer进而实现重用buffer的目的。

值得注意的是,该函数调用会直接清空buffer,因此在调用之前应当使用Flush处理buffer中的剩余数据。

如何获知有多少剩余空间?

可以使用bufio.Writer.Available()

bufio是否实现了ReaderFrom优化?有什么注意事项?

虽然bufio实现了ReaderFrom方法来优化io.Copy等函数的性能,但是仍然要使用Flush来写入剩余数据!

type Writer int

func (*Writer) Write(p []byte) (n int, err error) {
   
   
	fmt.Printf("%q\n", p)
	return len(p), nil
}

func main() {
   
   
	s := strings.NewReader("onetwothree")
	w := new(Writer)
	bw := bufio.NewWriterSize(w
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值