标准库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 ...
随机推荐
- 推荐一款简单易用线上引流测试工具:GoReplay
一. 引流测试产生背景 日常大部分的测试工作都是在测试环境下,通过模拟用户的行为来对系统进行验证,包括功能以及性能.在这个过程中,你可能会遇到以下问题: 用户访问行为比较复杂,模拟很难和用户行为一致, ...
- OptimalSolution(9)--其他问题(1)
一.从5随机到7及其扩展 题目1:给定一个等概率随机产生1~5的随机函数rand1to5: public int rand1To5() { return (int)(Math.random() * 5 ...
- Mysql数据库(五)表记录的检索
一.基本查询语句 二.单表查询 1.查询所有字段 mysql> SELECT * FROM tb_bookinfo; +----------+-----------+--------+----- ...
- jquery复习
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- FastJson的使用心得
本文为早前整理,参考文献已找不到,如有侵权请与我联系,添加参考链接. 一丶基本使用 1.1主要API fastjson入口类是com.alibaba.fastjson.JSON,主要的API是JS ...
- python str的一些操作及处理
一.str的定义:Python中凡是用引号引起来的数据可以称为字符串类型,组成字符串的每个元素称之为字符,将这些字符一个一个连接起来,然后在用引号起来就是字符串. 二.str的简单操作方法: conu ...
- ABP WebApi的请求类型
Api对应的请求类型分为以下四种方法: 1.POST 2.PUT 3.DELETE 4.GET 一般abp的请求类型都是根据接口命名来定义的,Create——POST,Delete——DELETE,U ...
- django & celery - 关于并发处理能力和内存使用的小结
背景 众所周知,celery 是python世界里处理分布式任务的好助手,它的出现结合赋予了我们强大的处理异步请求,分布式任务,周期任务等复杂场景的能力. 然鹅,今天我们所要讨论的则是如何更好的在使用 ...
- 看电影(movie):组合数
Description 到了难得的假期,小白班上组织大家去看电影.但由于假期里看电影的人太多,很难做到让全班看上同一场电影,最后大家在一个偏僻的小胡同里找到了一家电影院.但这家电影院分配座位的方式很特 ...
- 《吊打面试官》系列-Redis哨兵、持久化、主从、手撕LRU
你知道的越多,你不知道的越多 点赞再看,养成习惯 前言 Redis在互联网技术存储方面使用如此广泛,几乎所有的后端技术面试官都要在Redis的使用和原理方面对小伙伴们进行360°的刁难.作为一个在互联 ...