go语言读取缓冲区内容 golang逐行读取文件

Golang bytes.buffer详解Buffer 介绍
Buffer 是 bytes 包中的一个 type Buffer struct{…}
A buffer is a variable-sized buffer of bytes with Read and Write methods. The zero value for Buffer is an empty buffer ready to use.
(是一个变长的 buffer,具有 Read 和Write 方法 。Buffer 的 零值 是一个 空的 buffer,但是可以使用)
Buffer 就像一个集装箱容器 , 可以存东西,取东西(存取数据)
创建缓冲器
输出
写入到缓冲器
buffer在new的时候是空的,也是可以直接Write的
Write
结果
WriteString
结果
WriteByte
WriteRune
结果
从缓冲器中写出
读出缓冲器
Read
ReadByte
返回缓冲器头部的第一个byte
ReadRun
ReadRune方法,返回缓冲器头部的第一个rune
为什么n==3 , 而n1==1呢?我们看下ReadRune 的源码
ReadBytes
ReadBytes方法 , 需要一个byte作为分隔符,读的时候从缓冲器里找出第一个出现的分隔符,缓冲器头部开始到分隔符之间的byte返回 。
相当于有一个分隔符
ReadString
和readBytes方法类似
读入缓冲器
ReadFrom方法 , 从一个实现io.Reader接口的r,把r的内容读到缓冲器里,n返回读的数量
从缓冲器取出
Next方法,返回前n个byte(slice),原缓冲器变
缓冲区原理介绍
go字节缓冲区底层以字节切片做存储,切片存在长度len与容量cap, 缓冲区写从长度len的位置开始写,当lencap时,会自动扩容 。缓冲区读会从内置标记off位置开始读(off始终记录读的起始位置) , 当off==len时,表明缓冲区已全部读完
并重置缓冲区(len=off=0),此外当将要内容长度 已写的长度(即len) = cap/2时,缓冲区前移覆盖掉已读的内容(off=0,len-=off),从避免缓冲区不断扩容
golang中bufio包一、介绍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() 方法,对于实现这个接口的对象都是可以使用这两个方法的
注明:介绍内容来自博主 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
【go语言读取缓冲区内容 golang逐行读取文件】 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)
golang net/http包 http请求的字节码读取与解析 。先配置Header最长读取时间、req最长读取时间、req最大读取长度默认6M 。
RFC7230禁止\r\n参数go语言读取缓冲区内容,Url中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符以及所有保留字符 。但go net/http包放宽了这个要求 。
先构建newTextprotoReader,由于缓冲区是对象复用go语言读取缓冲区内容的,用完后要defer put 。共完以以下解析任务go语言读取缓冲区内容:
TextprotoReader数据结构,将字节码Reader转成文本Reader 。
第一步,从第一行解析出method uri prototype 。
第二步解析URL 。url.URL数据结构:
解析Scheme,协议前缀(小写) 。有查询参数?,则配置url.ForceQuery url.RawQuery 。有认证信息///...//,则解析url.User url.Host 。最后配置url.Path和url.RawPath,如果Path==RawPath,则RawPath="" 。
第三步解析MIMEHeader 。
第四步readTransfer 。重新配置如下参数:RequestMethod ProtoMajor ProtoMinor Header Trailer ContentLength Close 。对于Body,如果encodings支持chunked,读取流用chunkedReader包裹 。默认情况用LimitedReader , 无body赋空的struct{} 。
以下情况返回非空err,示得到正确的请求:
最后配置req.ctx req.RemoteAddr req.TLS body.doEarlyClose = true 。
构建Response:
其中closeNotifyCh必须在构建时初始化,没有content所以先置contentLength为-1 。
配置w.cw并被w.w包裹 。w.cw缓冲默认大小2M 。
获取Request可能出现如下错误:
先上响应数据结构:
response字段可以分类为:大对象、缓冲、KV对或bool型的状态参数 。
大对象有:
状态字段:
chunkWriter数据结构:
chunkWriter包裹了Response , 功能之一是完成Header设置,包括Content-TypeContent-Length chunk-header 。bufio.Writer是chunkWriter是缓冲包裹 。
handler将响应写入到response.w 。
调用w.w.Flush()将w写入到cw , 注意到Flush()操作,如果未刷空缓存并报错,触发拷贝操作 。报错不会退回已写出的数据 。
进而调用cw.Write(),根据cw.chunking参数 。
putBufioWriter(w.w)清空resp.w缓冲,如果池化放回sync.pool 。
根据chunkWriter的定义,w.cw.close()负责cw的结束工作:写入换行符和resp.trailers数据 。
最后刷新TCP缓冲w.conn.bufw.Flush(),完成响应包发送 。并正确关闭request 。
关于go语言读取缓冲区内容和golang逐行读取文件的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站 。

    推荐阅读