golang中bufio包

laijh · · 1077 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

一、介绍go标准库中的bufio
最近用golang写了一个处理文件的脚本,由于其中涉及到了文件读写,开始使用golang中的 io 包,后来发现golang 中提供了一个bufio的包,使用这个包可以大幅提高文件读写的效率,于是在网上搜索同样的文件读写为什么bufio 要比io 的读写更快速呢?根据网上的资料和阅读源码,以下来详细解释下bufio的高效如何实现的。

bufio 包介绍
bufio包实现了有缓冲的I/O。它包装一个io.Reader或io.Writer接口对象,创建另一个也实现了该接口,且同时还提供了缓冲和一些文本I/O的帮助函数的对象。

以上为官方包的介绍,在其中我们能了解到的信息如下:

bufio 是通过缓冲来提高效率

简单的说就是,把文件读取进缓冲(内存)之后再读取的时候就可以避免文件系统的io 从而提高速度。同理,在进行写操作时,先把文件写入缓冲(内存),然后由缓冲写入文件系统。看完以上解释有人可能会表示困惑了,直接把 内容->文件 和 内容->缓冲->文件相比, 缓冲区好像没有起到作用嘛。其实缓冲区的设计是为了存储多次的写入,最后一口气把缓冲区内容写入文件。下面会详细解释

bufio 封装了io.Reader或io.Writer接口对象,并创建另一个也实现了该接口的对象

io.Reader或io.Writer 接口实现read() 和 write() 方法,对于实现这个接口的对象都是可以使用这两个方法的


image.png

注明:介绍内容来自博主LiangWenT
,原文链接:https://blog.csdn.net/LiangWenT/article/details/78995468,在查找资料时,发现这篇博客的内容很好理解

bufio包实现了缓存IO。它包装了io.Reader和io.Write对象,创建了另外的Reader和Writer对象,它们也实现了io.Reader和io.Write接口,具有缓存。注意:缓存是放在主存中,既然是保存在主存里,断电会丢失数据,那么要及时保存数据。

二、常用内容
1、Reader类型

type Reader struct {
    buf                    []byte        // 缓存
    rd                      io.Reader // 底层的io.Reader 
    r, w                    int
    err                     error        // 读过程中遇到的错误
    lastByte             int            // 最后一次读到的字节      
    lastRuneSize     int            // 最后一次读到的Rune的大小  
}

NewReaderSize

func NewReaderSize(rd io.Reader, size int) *Reader

作用:NewReaderSize将rd封装成一个带缓存的bufio.Reader对象。缓存大小由size指定(如果小于16则会被设为16)。如果rd的基类型就是有足够缓存的bufio.Reader类型,则直接将rd转换为基类型返回。
NewReader

func NewReader(rd io.Reader) *Reader

funcReader相当于NewReaderSize(rd, 4096)
Peek

func (b *Reader) Peek(n int) ([]byte, error)

Peek返回缓存的一个切片,该切片引用缓存中前n个字节的数据,该操作不会将数据读出,只是引用,引用的数据在下一次读取操作之前有效的。如果切片长度小于n,则返回一个错误信息说明原因。如果n大于缓存的总大小,则返回ErrBufferFull。
Read

func (b *Reader) Read(p []byte) (n int, err error)

Read从b中数据到p中,返回读出的字节数和遇到的错误。如果缓存不为空,则只能读出缓冲中的数据,不会从底层io.Reader中提取数据,如果缓存为空,则:
1、len(p) >= 缓存大小,则跳过缓存,直接从底层io.Reader中读出到p中
2、len(p)< 缓存大小,则先将数据从底层io.Reader中读取到缓存中,再从缓存读取到p中。
Buffered

func (b *Reader) Buffered() int

Buffered返回缓存中未读取的数据的长度。
Discard

func (b *Reader) Discard(n int) (discarded int, err error)

Discard跳过后续的n个字节的数据,返回跳过的字节数。

Writer类型和方法
write结构

type Write struct {
    err  error      // 写过程中遇到的错误
    buf []byte    // 缓存
    n    int         // 当前缓存中的字节数
    wr  io.Write // 底层的io.Writer对象
}

NewWriteSize

func NewWriteSize(wr io.Write, size int) *Write

NewWriterSize将wr封装成一个带缓存的bufio.Writer对象,缓存大小由size指定(如果小于4096则会被设置未4096)。
NewWrite

func NewWriter(wr io.Writer) *Writer

NewWriter相等于NewWriterSize(wr, 4096)

WriteString

func (b *Write) WriteString(s string) (int, error)

WriteString功能同Write,只不过写入的是字符串
WriteRune

func (b *Writer) WriteRune(r rune) (size int, err error)

WriteRune向b写入r的UTF-8编码,返回r的编码长度。
Flush

func (b *Writer) Flush() error

Available

func (b *Writer) Available() int

Available 返回缓存中未使用的空间的长度
Buffered

func (b *Writer) Buffered() int

Buffered返回缓存中未提交的数据长度
Reset

func (b *Write) Reset(w io.Writer)

Reset将b的底层Write重新指定为w,同时丢弃缓存中的所有数据,复位所有标记和错误信息。相当于创建了一个新的bufio.Writer。

GO中还提供了Scanner类型,处理一些比较简单的场景。如处理按行读取输入序列或空格分隔的词等。


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:laijh

查看原文:golang中bufio包

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1077 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传