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

即:为了解决CPU与磁盘IO速度不匹配问题,我们利用buffio将提供给CPU的数据缓存到buff内存中,然后进行读写,提高读写效率。所以我们就需要创建一个buffio对象,然后将需要操作的数据传递给它,然后再封装返回一个高速读写的buffio对象。

所以可以总结为以下步骤:

1. 创建一个buffio对象。

2. 将一个普通读取数据传递给上一个高速buffio对象。

3. buffio接收数据后返回一个高速操作对象。

type Reader

type Reader struct {
// 内含隐藏或非导出字段
}

Reader实现了给一个io.Reader接口对象附加缓冲。这个就是封装后返回高速读写对象

func NewReader

func NewReader(rd io.Reader) *Reader

NewReader创建一个具有默认大小缓冲、从r读取的*Reader。创建一个用户接受普通数据的NewReader对象,接收的参数是一个实现了普通io.Reader的接口。从字面意义也能看出接收的是一个io.Reader 返回的也是一个 Reader

func NewReaderSize

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

NewReaderSize创建一个具有最少有size尺寸的缓冲、从r读取的*Reader。如果参数r已经是一个具有足够大缓冲的* Reader类型值,会返回r。和上一个的差别是创建时设置了高速缓冲区的大小。

func (*Reader) Reset

func (b *Reader) Reset(r io.Reader)

Reset丢弃缓冲中的数据,清除任何错误,将b重设为其下层从r读取数据。清空(高速)缓冲区中的数据

func (*Reader) Buffered

func (b *Reader) Buffered() int

Buffered返回缓冲中现有的可读取的字节数。统计(高速)缓冲区中的字节数,并返回

func (*Reader) Peek

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

Peek返回输入流的下n个字节,而不会移动读取位置。返回的[]byte只在下一次调用读取操作前合法。如果Peek返回的切片长度比n小,它也会返会一个错误说明原因。如果n比缓冲尺寸还大,返回的错误将是ErrBufferFull。

即:返回的如果不是我们指定的n个字节,无论大小都会报错

// Peek 返回缓存的一个切片,该切片引用缓存中前 n 字节数据
// 该操作不会将数据读出,只是引用
// 引用的数据在下一次读取操作之前是有效的
// 如果引用的数据长度小于 n,则返回一个错误信息
// 如果 n 大于缓存的总大小,则返回 ErrBufferFull
// 通过 Peek 的返回值,可以修改缓存中的数据
// 但是不能修改底层 io.Reader 中的数据

func (*Reader) ReadByte 

func (b *Reader) ReadByte() (c byte, err error)

ReadByte读取并返回一个字节。如果没有可用的数据,会返回错误。

// ReadByte 从 b 中读出一个字节并返回
// 如果 b 中无可读数据,则返回一个错误

func (*Reader) UnreadByte

func (b *Reader) UnreadByte() error

UnreadByte吐出最近一次读取操作读取的最后一个字节。(只能吐出最后一个,多次调用会出问题)

// UnreadByte 撤消最后一次读出的字节
// 只有最后读出的字节可以被撤消
// 无论任何操作,只要有内容被读出,就可以用 UnreadByte 撤消一个字节

func (*Reader) ReadRune

func (b *Reader) ReadRune() (r rune, size int, err error)

ReadRune读取一个utf-8编码的unicode码值,返回该码值、其编码长度和可能的错误。如果utf-8编码非法,读取位置只移动1字节,返回U+FFFD,返回值size为1而err为nil。如果没有可用的数据,会返回错误。

func (*Reader) UnreadRune

func (b *Reader) UnreadRune() error

UnreadRune吐出最近一次ReadRune调用读取的unicode码值。如果最近一次读取不是调用的ReadRune,会返回错误。(从这点看,UnreadRune比UnreadByte严格很多)

// ReadRune 从 b 中读出一个 UTF8 编码的字符并返回
// 同时返回该字符的 UTF8 编码长度
// 如果 UTF8 序列无法解码出一个正确的 Unicode 字符
// 则只读出 b 中的一个字节,并返回 U+FFFD 字符,size 返回 1
func (b *Reader) ReadRune() (r rune, size int, err error)

// UnreadRune 撤消最后一次读出的 Unicode 字符
// 如果最后一次执行的不是 ReadRune 操作,则返回一个错误
// 因此,UnreadRune 比 UnreadByte 更严格

func (*Reader) ReadBytes

func (b *Reader) ReadBytes(delim byte) (line []byte, err error)

ReadBytes读取直到第一次遇到delim字节,返回一个包含已读取的数据和delim字节的切片。如果ReadBytes方法在读取到delim之前遇到了错误,它会返回在错误之前读取的数据以及该错误(一般是io.EOF)。当且仅当ReadBytes方法返回的切片不以delim结尾时,会返回一个非nil的错误。

// ReadBytes 在 b 中查找 delim 并读出 delim 及其之前的所有数据
// 如果 ReadBytes 在找到 delim 之前遇到错误
// 则返回遇到错误之前的所有数据,同时返回遇到的错误(通常是 io.EOF)
// 只有当 ReadBytes 找不到 delim 时,err 才不为 nil
// 对于简单的用途,使用 Scanner 可能更方便

func (*Reader) ReadString

func (b *Reader) ReadString(delim byte) (line string, err error)

ReadString读取直到第一次遇到delim字节,返回一个包含已读取的数据和delim字节的字符串。如果ReadString方法在读取到delim之前遇到了错误,它会返回在错误之前读取的数据以及该错误(一般是io.EOF)。当且仅当ReadString方法返回的切片不以delim结尾时,会返回一个非nil的错误。

func (*Reader) ReadLine

func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error)

ReadLine是一个低水平的行数据读取原语。大多数调用者应使用ReadBytes('\n')或ReadString('\n')代替,或者使用Scanner。

ReadLine尝试返回一行数据,不包括行尾标志的字节。如果行太长超过了缓冲,返回值isPrefix会被设为true,并返回行的前面一部分。该行剩下的部分将在之后的调用中返回。返回值isPrefix会在返回该行最后一个片段时才设为false。返回切片是缓冲的子切片,只在下一次读取操作之前有效。ReadLine要么返回一个非nil的line,要么返回一个非nil的err,两个返回值至少一个非nil。

返回的文本不包含行尾的标志字节("\r\n"或"\n")。如果输入流结束时没有行尾标志字节,方法不会出错,也不会指出这一情况。在调用ReadLine之后调用UnreadByte会总是吐出最后一个读取的字节(很可能是该行的行尾标志字节),即使该字节不是ReadLine返回值的一部分。

func (*Reader) ReadSlice

func (b *Reader) ReadSlice(delim byte) (line []byte, err error)

ReadSlice读取直到第一次遇到delim字节,返回缓冲里的包含已读取的数据和delim字节的切片。该返回值只在下一次读取操作之前合法。如果ReadSlice放在在读取到delim之前遇到了错误,它会返回在错误之前读取的数据在缓冲中的切片以及该错误(一般是io.EOF)。如果在读取到delim之前缓冲就被写满了,ReadSlice失败并返回ErrBufferFull。因为ReadSlice的返回值会被下一次I/O操作重写,调用者应尽量使用ReadBytes或ReadString替代本法功法。当且仅当ReadBytes方法返回的切片不以delim结尾时,会返回一个非nil的错误。

func (*Reader) WriteTo

func (b *Reader) WriteTo(w io.Writer) (n int64, err error)

WriteTo方法实现了io.WriterTo接口。

type Writer

type Writer struct {
// 内含隐藏或非导出字段
}

Writer实现了为io.Writer接口对象提供缓冲。如果在向一个Writer类型值写入时遇到了错误,该对象将不再接受任何数据,且所有写操作都会返回该错误。在说有数据都写入后,调用者有义务调用Flush方法以保证所有的数据都交给了下层的io.Writer。

Example

func NewWriter

func NewWriter(w io.Writer) *Writer

NewWriter创建一个具有默认大小缓冲、写入w的*Writer。

func NewWriterSize

func NewWriterSize(w io.Writer, size int) *Writer

NewWriterSize创建一个具有最少有size尺寸的缓冲、写入w的*Writer。如果参数w已经是一个具有足够大缓冲的*Writer类型值,会返回w。

func (*Writer) Reset

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

Reset丢弃缓冲中的数据,清除任何错误,将b重设为将其输出写入w。

func (*Writer) Buffered

func (b *Writer) Buffered() int

Buffered返回缓冲中已使用的字节数。

func (*Writer) Available

func (b *Writer) Available() int

Available返回缓冲中还有多少字节未使用。

func (*Writer) Write

func (b *Writer) Write(p []byte) (nn int, err error)

Write将p的内容写入缓冲。返回写入的字节数。如果返回值nn < len(p),还会返回一个错误说明原因。

func (*Writer) WriteString

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

WriteString写入一个字符串。返回写入的字节数。如果返回值nn < len(s),还会返回一个错误说明原因。

func (*Writer) WriteByte

func (b *Writer) WriteByte(c byte) error

WriteByte写入单个字节。

func (*Writer) WriteRune

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

WriteRune写入一个unicode码值(的utf-8编码),返回写入的字节数和可能的错误。

func (*Writer) Flush

func (b *Writer) Flush() error

Flush方法将缓冲中的数据写入下层的io.Writer接口。

func (*Writer) ReadFrom

func (b *Writer) ReadFrom(r io.Reader) (n int64, err error)

ReadFrom实现了io.ReaderFrom接口。

############################################################

type ReadWriter

type ReadWriter struct {
*Reader
*Writer
}

ReadWriter类型保管了指向Reader和Writer类型的指针,(因此)实现了io.ReadWriter接口。

func NewReadWriter

func NewReadWriter(r *Reader, w *Writer) *ReadWriter

NewReadWriter申请创建一个新的、将读写操作分派给r和w 的ReadWriter。

type SplitFunc

type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error)

SplitFunc类型代表用于对输出作词法分析的分割函数。

参数data是尚未处理的数据的一个开始部分的切片,参数atEOF表示是否Reader接口不能提供更多的数据。返回值是解析位置前进的字节数,将要返回给调用者的token切片,以及可能遇到的错误。如果数据不足以(保证)生成一个完整的token,例如需要一整行数据但data里没有换行符,SplitFunc可以返回(0, nil, nil)来告诉Scanner读取更多的数据写入切片然后用从同一位置起始、长度更长的切片再试一次(调用SplitFunc类型函数)。

如果返回值err非nil,扫描将终止并将该错误返回给Scanner的调用者。

除非atEOF为真,永远不会使用空切片data调用SplitFunc类型函数。然而,如果atEOF为真,data却可能是非空的、且包含着未处理的文本。

func ScanBytes

func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error)

ScanBytes是用于Scanner类型的分割函数(符合SplitFunc),本函数会将每个字节作为一个token返回。

func ScanRunes

func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error)

ScanRunes是用于Scanner类型的分割函数(符合SplitFunc),本函数会将每个utf-8编码的unicode码值作为一个token返回。本函数返回的rune序列和range一个字符串的输出rune序列相同。错误的utf-8编码会翻译为U+FFFD = "\xef\xbf\xbd",但只会消耗一个字节。调用者无法区分正确编码的rune和错误编码的rune。

func ScanWords

func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error)

ScanRunes是用于Scanner类型的分割函数(符合SplitFunc),本函数会将空白(参见unicode.IsSpace)分隔的片段(去掉前后空白后)作为一个token返回。本函数永远不会返回空字符串。

func ScanLines

func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error)

ScanRunes是用于Scanner类型的分割函数(符合SplitFunc),本函数会将每一行文本去掉末尾的换行标记作为一个token返回。返回的行可以是空字符串。换行标记为一个可选的回车后跟一个必选的换行符。最后一行即使没有换行符也会作为一个token返回。

type Scanner

type Scanner struct {
// 内含隐藏或非导出字段
}

Scanner类型提供了方便的读取数据的接口,如从换行符分隔的文本里读取每一行。

成功调用的Scan方法会逐步提供文件的token,跳过token之间的字节。token由SplitFunc类型的分割函数指定;默认的分割函数会将输入分割为多个行,并去掉行尾的换行标志。本包预定义的分割函数可以将文件分割为行、字节、unicode码值、空白分隔的word。调用者可以定制自己的分割函数。

扫描会在抵达输入流结尾、遇到的第一个I/O错误、token过大不能保存进缓冲时,不可恢复的停止。当扫描停止后,当前读取位置可能会远在最后一个获得的token后面。需要更多对错误管理的控制或token很大,或必须从reader连续扫描的程序,应使用bufio.Reader代替。

Example (Custom)
Example (Lines)
Example (Words)

func NewScanner

func NewScanner(r io.Reader) *Scanner

NewScanner创建并返回一个从r读取数据的Scanner,默认的分割函数是ScanLines。

func (*Scanner) Split

func (s *Scanner) Split(split SplitFunc)

Split设置该Scanner的分割函数。本方法必须在Scan之前调用。

func (*Scanner) Scan

func (s *Scanner) Scan() bool

Scan方法获取当前位置的token(该token可以通过Bytes或Text方法获得),并让Scanner的扫描位置移动到下一个token。当扫描因为抵达输入流结尾或者遇到错误而停止时,本方法会返回false。在Scan方法返回false后,Err方法将返回扫描时遇到的任何错误;除非是io.EOF,此时Err会返回nil。

func (*Scanner) Bytes

func (s *Scanner) Bytes() []byte

Bytes方法返回最近一次Scan调用生成的token。底层数组指向的数据可能会被下一次Scan的调用重写。

func (*Scanner) Text

func (s *Scanner) Text() string

Bytes方法返回最近一次Scan调用生成的token,会申请创建一个字符串保存token并返回该字符串。

func (*Scanner) Err

func (s *Scanner) Err() error

Err返回Scanner遇到的第一个非EOF的错误。

Go基础篇【第4篇】: 内置库模块 bufio的更多相关文章

  1. Go基础篇【第8篇】: 内置库模块 bytes [二]

    type Reader ¶ type Reader struct { // 内含隐藏或非导出字段 } Reader类型通过从一个[]byte读取数据,实现了io.Reader.io.Seeker.io ...

  2. Go基础篇【第1篇】: 内置库模块 OS

    os包提供了操作系统函数的不依赖平台的接口.设计为Unix风格的,虽然错误处理是go风格的:失败的调用会返回错误值而非错误码.通常错误值里包含更多信息.os包的接口规定为在所有操作系统中都是一致的.非 ...

  3. Go基础篇【第5篇】: 内置库模块 exec

    Package exec runs external commands. It wraps os.StartProcess to make it easier to remap stdin and s ...

  4. Go基础篇【第8篇】: 内置库模块 bytes [一]

    bytes包实现了操作[]byte的常用函数.本包的函数和strings包的函数相当类似. func Compare func Compare(a, b []byte) int Compare函数返回 ...

  5. Go基础篇【第6篇】: 内置库模块 flag

    import "flag" flag包实现了命令行参数的解析.每个参数认为一条记录,根据实际进行定义,到一个set集合.每条都有各自的状态参数. 在使用flag时正常流程: 1.  ...

  6. Go基础篇【第2篇】: 内置库模块 fmt

    fmt官方文档说明:https://studygolang.com/pkgdoc import "fmt" mt包实现了类似C语言printf和scanf的格式化I/O.格式化动作 ...

  7. Go内置库模块 flag

    import "flag" flag包实现了命令行参数的解析.每个参数认为一条记录,根据实际进行定义,到一个set集合.每条都有各自的状态参数. 在使用flag时正常流程: 1.  ...

  8. day05 模块以及内置常用模块用法

    内置常用模块详解: 1 time 2 datetime 3 random   4 os 5 sys 6 shutil 7 shelve 8 xml 9 configparser 10 hashlib ...

  9. 【CobaltStrike】对CobaltStrike内置功能模块的了解

    对CobaltStrike内置功能模块的了解 0x00 右键功能列表 Interact 打开beacon Access dump hashes 获取hash Elevate 提权 Golden Tic ...

随机推荐

  1. mssql数据库迁移到mysql

    使用mysql migration toolkit工具来进行迁移.(需要安装jdk6 java的安装包) 发现数据量大的表却没能迁过来.软件使用比较容易,配置下源数据库信息,和目标数据库信息就可以进行 ...

  2. SpringBoot非官方教程 | 第十篇: 用spring Restdocs创建API文档

    转载请标明出处: 原文首发于:https://www.fangzhipeng.com/springboot/2017/07/11/springboot10-springrestdocs/ 本文出自方志 ...

  3. Android 初步-Android文件目录介绍

    src:存放的是应用程序使用到的java文件. gen:系统自动生成的目录,不需要程序员进行修改,包含了R.java文件.该文件包含了 程序使用到的资源文件对应的唯一资源ID,注意:如果R文件生成错误 ...

  4. Python常用模块之json、pickle、random、hashlib、collections

    1.json和pickle json用于字符串和Python数据类型间进行转换pickle用于python特有的类型和python的数据类型间进行转换json和pickle均提供了四种方法dumps, ...

  5. PTA 最多删除3个字符(DP) - 30分

    给定一个全部由小写英文字母组成的字符串,允许你至多删掉其中 3 个字符,结果可能有多少种不同的字符串? 输入格式: 输入在一行中给出全部由小写英文字母组成的.长度在区间 [4, 1] 内的字符串. 输 ...

  6. 【2018 ICPC焦作网络赛 K】Transport Ship(多重背包二进制优化)

    There are N different kinds of transport ships on the port. The ith kind of ship can carry the weigh ...

  7. ABAP术语-Lock Mode

    Lock Mode 原文:http://www.cnblogs.com/qiangsheng/archive/2008/02/29/1085732.html Status that determine ...

  8. CDN初识

    CDN 全称:Content Delivery Network或Content Ddistribute Network,即内容分发网络,通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层 ...

  9. Java处理中文乱码问题

    package servlet; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.ser ...

  10. 吐血分享:QQ群霸屏技术教程2017(问题篇)

    霸屏技术,问题篇后,暂时搁置,尔望后续. 这里针对操作中,经常遇到的问题,做个简单整理. 回忆下,排名流程. 1.建群,品牌产品群,做任何关键词都是品牌产品群,皆因其有独特的优势. 2.拉人,填充群人 ...