之前的几篇文章详细介绍了 io 包,io 包为 IO 原语(I/O primitives)提供了基本的操作接口。接下来要讲解的 bufio 包相比 io 包提供了带缓冲的 io 操作,首先讲解下带缓冲与不带缓冲的区别和联系。
如何理解不带缓冲 I/O ?
不带缓冲的 I/O 操作是指应用程序直接调用操作系统的系统调用函数来完成,而不是先将数据放入一个缓冲区,然后从缓冲区中读写数据。语言本身提供的不带缓冲的 I/O 操作是指进程不提供缓冲功能(但内核还是提供缓冲的,系统内核对磁盘的读写都会提供一个块缓冲,写数据时,先将数据写入到块缓冲排队,当块缓冲达到一定量时,再把数据写入到磁盘)。
Golang标准库中的 io 包提供的是不带缓冲的读写操作,每次操作都会进行系统调用。
如何理解带缓冲 I/O?
带缓冲的 I/O 是指进程在进行 I/O 操作时提供了一个缓冲区,数据会先被读取到一个缓冲区中,当达到一定条件,比如流缓冲区满了或刷新缓冲区时,再从缓冲区中读取或写入,才会产生系统调用。
Golang 标准库中的 bufio 包提供了带缓冲的读写操作函数,在读写文件或网络数据时,可以使用 bufio 包来提高效率。例如,从一个大文件中读取数据时,可以使用 bufio.Reader 来每次读取一些数据到缓冲区中,然后从缓冲区中读取数据,避免每次读取都进行系统调用,提高效率。同样地,当需要将大量数据写入文件或网络时,可以使用 bufio.Writer 来每次将数据先写入缓冲区,然后再一次性将缓冲区中的数据写入文件中。
带缓冲 I/O 相比不带缓冲 I/O 的优势
带缓冲 I/O 可以减少系统调用的次数,提高执行效率。内核与外围设备的数据交换,内核与用户空间的数据交换都是比较费时的,使用缓冲区大大优化了这些费时的操作。
小结
本文介绍了带缓冲和不带缓冲的 IO 操作,可以看出带缓冲的 I/O 提供了一个缓冲区,数据会先被读取到一个缓冲区中,当达到一定条件,再从缓冲区中读取或写入,才会产生系统调用。相对于不带缓冲的 I/O 操作,减少了系统调用的次数,提高了执行效率。接下来的几篇文章会详细讲解 bufio 包相关的知识。