重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
一、介绍go标准库中的bufio
创新互联专注于企业成都全网营销推广、网站重做改版、武强网站定制设计、自适应品牌网站建设、H5开发、成都商城网站开发、集团公司官网建设、外贸营销网站建设、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为武强等各大城市提供网站开发制作服务。
最近用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() 方法,对于实现这个接口的对象都是可以使用这两个方法的
注明:介绍内容来自博主 LiangWenT
,原文链接: ,在查找资料时,发现这篇博客的内容很好理解
bufio包实现了缓存IO。它包装了io.Reader和io.Write对象,创建了另外的Reader和Writer对象,它们也实现了io.Reader和io.Write接口,具有缓存。注意:缓存是放在主存中,既然是保存在主存里,断电会丢失数据,那么要及时保存数据。
二、常用内容
1、Reader类型
NewReaderSize
作用:NewReaderSize将rd封装成一个带缓存的bufio.Reader对象。缓存大小由size指定(如果小于16则会被设为16)。如果rd的基类型就是有足够缓存的bufio.Reader类型,则直接将rd转换为基类型返回。
NewReader
funcReader相当于NewReaderSize(rd, 4096)
Peek
Peek返回缓存的一个切片,该切片引用缓存中前n个字节的数据,该操作不会将数据读出,只是引用,引用的数据在下一次读取操作之前有效的。如果切片长度小于n,则返回一个错误信息说明原因。如果n大于缓存的总大小,则返回ErrBufferFull。
Read
Read从b中数据到p中,返回读出的字节数和遇到的错误。如果缓存不为空,则只能读出缓冲中的数据,不会从底层io.Reader中提取数据,如果缓存为空,则:
1、len(p) = 缓存大小,则跳过缓存,直接从底层io.Reader中读出到p中
2、len(p) 缓存大小,则先将数据从底层io.Reader中读取到缓存中,再从缓存读取到p中。
Buffered
Buffered返回缓存中未读取的数据的长度。
Discard
Discard跳过后续的n个字节的数据,返回跳过的字节数。
Writer类型和方法
write结构
NewWriteSize
NewWriterSize将wr封装成一个带缓存的bufio.Writer对象,缓存大小由size指定(如果小于4096则会被设置未4096)。
NewWrite
NewWriter相等于NewWriterSize(wr, 4096)
WriteString
WriteString功能同Write,只不过写入的是字符串
WriteRune
WriteRune向b写入r的UTF-8编码,返回r的编码长度。
Flush
Available
Available 返回缓存中未使用的空间的长度
Buffered
Buffered返回缓存中未提交的数据长度
Reset
Reset将b的底层Write重新指定为w,同时丢弃缓存中的所有数据,复位所有标记和错误信息。相当于创建了一个新的bufio.Writer。
GO中还提供了Scanner类型,处理一些比较简单的场景。如处理按行读取输入序列或空格分隔的词等。
内容来自:
参考链接:
1)
2)
先看一下目录结构,注意这里的src名称是必须的,go在设置了GOPATH后,默认会添加src去寻找package,暂未查询是否有方法不按照src查询
根据上面的描述,Go语言中通过包中函数的名称来区分公共函数和私有函数,我们在main函数中是无法调用myPrivateFunc的
此时如果执行通过go run方式执行,会看到如下的提示信息,这与大部分语言对于包管理方式相关,所以我们通过两种不同的方法来让代码执行起来
返回如下,这里面对我们后续执行有影响的两个参数GO111MODULE和GOPATH
如果要使用gopath模式引用包,则需要关闭mod模式
设置GOPATH为当前路径,即main.go所在的路径
此时再查看go env时,GOPATH已经发生改变
我们再次尝试执行代码
可以看到public函数被调用
你需要设置 GOPATH 环境变量
你 main.go 中需要 import 相应包
你 调用处需要带上包前缀,比如 tempconv.FToC
⑴ Go Kit
它本身不是一个框架,而是一套微服务工具集,可以用于解决分布式系统开发中的大多数常见问题,所以使用者可以专注于你的业务逻辑中。
⑵ Gingko
是一个Go测试框架,目的是帮助我们使用行为驱动开发风格高效地编写富有表现力和全面的测试,它有着非常良好的帮助文档,任何人都可以轻松地在项目中集成使用它。
⑶ NSQ
实时分布式消息传递平台,提供高可用性和可靠的消息传递保证,可以水平扩展,支持负载均衡,安装部署非常方便。
⑷ Goose
Golang中最佳的数据库迁移包,通过创建增量SQL更改和Go函数来管理数据库结构,在Go1.16版本以上,还支持了嵌入式sql迁移。
⑸ GORM
是一个功能齐全的Golang对象关系映射库,是一种开发人员友好的工具,用于在不兼容的类型系统之间转换数据,专门设计用于在类型系统之间切换时最大限度地减少重写代码。
⑹ Authboss
一个模块化的身份验证包,使用它你可以快速地在项目中进行身份验证管理。它有几个常见的身份验证和授权模块供开发人员选择。
⑺ cli
是一个简单快捷的命令行管理包,用于为Go语言构建命令行应用程序,允许开发人员开发自己的富有表现力的命令行应用程序,用于创建标志、bash完成例程并生成帮助文本。
⑻ Vegeta
是一个用于HTTP负载测试的工具包,这个多功能工具专为测试具有恒定请求率的HTTP服务而设计。它可以有效地分析程序中的潜在问题,是一个始终贯穿以提高整体性能为目的的包。