标准库bufio个人详解
本文是我有通俗的语言写的如果有误请指出。
先看bufio官方文档
https://studygolang.com/pkgdoc文档地址

主要分三部分Reader、Writer、Scanner
分别是读数据、写数据和扫描器三种数据类型的相关操作 这个扫描后面会详细说我开始也没弄明白其实很简单。
Reader
func NewReaderSize
func NewReaderSize(rd io.Reader, size int) *Reader
NewReaderSize创建一个具有最少有size尺寸的缓冲、从r读取的*Reader。如果参数r已经是一个具有足够大缓冲的* Reader类型值,会返回r。
解释:看官方解释这个方法可能不太容易懂,这个意思就是就是你可以给*Reader自定义一个size大小的缓冲区,*Reader每次从底层io.Reader(也就是你那个文件或者流)中预读size大小的数据到缓冲区中(可能读不满),然后你每次读数据实际是从这个缓冲区中拿数据。

下面是NewReaderSize源码
func NewReaderSize(rd io.Reader, size int) *Reader {
// Is it already a Reader?
b, ok := rd.(*Reader)
if ok && len(b.buf) >= size {
return b
}
if size < minReadBufferSize { //minReadBufferSize==16
size = minReadBufferSize
}
r := new(Reader)
r.reset(make([]byte, size), rd)
return r
}
r.reset 初始化了一个*Reader 返回大小是size。
func NewReader
func NewReader(rd io.Reader) *Reader
NewReader创建一个具有默认大小缓冲、从r读取的*Reader。
解释:那这个NewReader就很好解释了 和NewReaderSize基本一样就是缓冲区大小是默认设置好的
func (*Reader) Peek
func (b *Reader) Peek(n int) ([]byte, error)
解释:Peek就是返回缓存的一个切片,该切片引用缓存中的前N个字节的数据,如果n大于总大小,则返回能读到的字节数的数据。
func (*Reader) Read
func (b *Reader) Read(p []byte) (n int, err error)
Read读取数据写入p。本方法返回写入p的字节数。本方法一次调用最多会调用下层Reader接口一次Read方法,因此返回值n可能小于len(p)。读取到达结尾时,返回值n将为0而err将为io.EOF。
解释:如果缓存不为空则直接从缓存中读数据不会从底层io.Reader读,如果缓存为空len(p)>缓存大小,则直接从底层io.Reader读数据到p。
如果len(p)<缓存大小,则先从底层io.Reader中读数据到缓存再到p。
主要就这几个 还有几个文档写的都很清楚易懂我就不多写了。
Writer类型的方法和Reader类型的方法差不多也很易懂主要就一个Flush要注意。
func (*Writer) Flush
func (b *Writer) Flush() error
Flush方法将缓冲中的数据写入下层的io.Writer接口。
和Reader是倒过来的,Writer每次写数据是先写入缓冲区的,进程缓冲区填满后,通过进程缓冲写入到内核缓冲再写入到磁盘,使用Flush就不等填满直接走写入流程了,保证你的数据及时写入文件。

解释:scanner类型扫描器 官方的说法很复杂,我也没太看懂找了很多资料,其实就是你在数据传输的时候时候使用“分隔符”,scanner类型可以通过分隔符逐个迭代你的数据。
上面4个函数func Scan…… 就是分隔符的判断函数这4个是给你预设好的,你也可以按照自己的需求改写。
怎么改写呢,看下面
func (*Scanner) Split
func (s *Scanner) Split(split SplitFunc)
这个Split方法就是设置你这个scanner的用哪个SplitFunc类型的函数
在看下面这个SpliFunc类型的函数签名
type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error)
照着这个格式写一个不就得了么,当然具体写法给出了但是你不会?没关系咱看一下官方是咋写的。
https://github.com/golang/go/blob/master/src/bufio/scan.go?name=release#57官方源码地址
func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error) {
if atEOF && len(data) == 0 {
return 0, nil, nil
}
if i := bytes.IndexByte(data, '\n'); i >= 0 {
// We have a full newline-terminated line.
return i + 1, dropCR(data[0:i]), nil
}
// If we're at EOF, we have a final, non-terminated line. Return it.
if atEOF {
return len(data), dropCR(data), nil
}
// Request more data.
return 0, nil, nil
}
看bytes.IndexByte(data, '\n');这段不就是在找行尾嘛 比如你想改成以“;”为分隔符的就改成bytes.IndexByte(data, ';');不就得了么
func main(){
scanner:=bufio.NewScanner(
strings.NewReader("abcdefg\nhigklmn"),
)
scanner.Split(ScanLines) //这里可以随意选择用哪个函数也可以自定义,可以不指定默认为\n做分隔符
for scanner.Scan(){
fmt.Println(scanner.Text())
}
}
到此为止拉~
标准库bufio个人详解的更多相关文章
- c/c++ 标准库 插入迭代器 详解
标准库 插入迭代器 详解 插入迭代器作用:copy等函数不能改变容器的大小,所以有时copy先容器是个空的容器,如果不使用插入迭代器,是无法使用copy等函数的. 例如下面的代码就是错误的: list ...
- c/c++ 标准库 bind 函数 详解
标准库 bind 函数 详解 bind函数:接收一个函数名作为参数,生成一个新的函数. auto newCallable = bind(callbale, arg_list); arg_list中的参 ...
- C++的iostream标准库介绍+使用详解(转)
0 为什么需要iostream 我们从一开始就一直在利用C++的输入输出在做着各种练习,输入输出是由iostream库提供的,所以讨论此标准库是有必要的,它与C语言的 stdio库不同,它从一开始就是 ...
- C++标准库vector类型详解
Vector简介 vector是定义在C++标准模板库,它是一个多功能.能够操作多种数据结构和算法的模板类(关于模板类我们后面会介绍,如何创建自己的模板类).vector是一个容器,能够像容器一样存放 ...
- 【Solr】索引库查询界面详解
目录 索引库查询界面详解 回到顶部 索引库查询界面详解 q:主查询条件.完全支持lucene语法.还进行了扩展. fq:过滤查询.是在主查询条件查询结果的基础上进行过滤.例如:product_pric ...
- 全网最全的Windows下Python2 / Python3里正确下载安装用来向微信好友发送消息的itchat库(图文详解)
不多说,直接上干货! 建议,你用Anaconda2或Anaconda3. 见 全网最全的Windows下Anaconda2 / Anaconda3里正确下载安装用来向微信好友发送消息的itchat库( ...
- python中requests库使用方法详解
目录 python中requests库使用方法详解 官方文档 什么是Requests 安装Requests库 基本的GET请求 带参数的GET请求 解析json 添加headers 基本POST请求 ...
- 【Linux开发】Linux下jpeglib库的安装详解
Linux下jpeglib库的安装详解 首先要下载所需的库压缩包:jpegsrc.v6b.tar.gz或 jpegsrc.v8b.tar.gz 然后将下载的压缩包随便放在和解压到你喜欢的地方. # t ...
- 常用开发库 - 告別BeanUtils拷贝,MapStruct工具库最全详解
常用开发库 - MapStruct工具库详解 MapStruct是一款非常实用Java工具,主要用于解决对象之间的拷贝问题,比如PO/DTO/VO/QueryParam之间的转换问题.区别于BeanU ...
随机推荐
- python编程系列---最详细的讲解进程与线程的关系
进程与线程 先引入三个比如: cpu---公司 进程---办公室 线程---程序员(我们) 全局变量,内存等资源---公司提供的电脑,桌子等 进程: 操作系统分配程序执行资源的单位 线程:进 ...
- Ubuntu 14.04 kylin 安装 OpenCV 2.4.9|3.0.0
首先安装依赖 sudo apt-get -y install libopencv-dev sudo apt-get -y install build-essential checkinstall cm ...
- 类和对象(day19整理)
目录 面对对象和面对过程编程 什么是面向对象 什么是面向过程编程 什么是面对对象编程 类 类的定义 定义类时发生的事情 __dict__和. 对象 名称空间 __init__函数 调用类发生的事情 对 ...
- 变量 + 数据类型(数字 + 字符串)(day03整理)
目录 一.上节课回顾 四 编程语言分类 (一) 机器语言 (二)汇编语言 (三) 高级语言 (四) 网络瓶颈效应 五.执行python程序两种方式 (一) 交互式(jupytre) (二) 命令行式( ...
- ajax同步请求与异步请求的区别
ajax 区别: async:布尔值,用来说明请求是否为异步模式.async是很重要的,因为它是用来控制JavaScript如何执行该请求. 当设置为true时,将以异步模式发送该请求,JavaScr ...
- Java基础(一)对象构造
由于Java对象构造非常重要,所以Java提供了多种编写构造器的机制. 1.重载 如果多个方法有相同的名字.不同的参数,便产生了重载.编译器必须挑选出具体执行哪个方法,它通过用各个方法给出的参数类型与 ...
- Spring为IOC容器注入Bean的五种方式
一 @Import导入组件,id默认是组件的全类名 //类中组件统一设置.满足当前条件,这个类中配置的所有bean注册才能生效: @Conditional({WindowsCondition.clas ...
- foreach数组并直接改变数组内容
<?php $arr = array(1, 2, 3, 4); foreach ($arr as &$value) { $value = $value * 2; } // $arr is ...
- Microsoft.Extensions.DependencyInjection 之三:展开测试
目录 前文回顾 IServiceCallSite CallSiteFactory ServiceProviderEngine CompiledServiceProviderEngine Dynamic ...
- CentOS 7下MySQL 5.7安装
5.7和之前版本的MySQL有一些不同,现把CentOS 7下MySQL 5.7安装.配置与应用完整过程记下来,或许对新手来说有用. 本文描述的安装是采用通用的二进制压缩包(linux – Gener ...