注册 登录

清河洛

Go中io缓冲区操作的bufio包

qingheluo2024-07-12清河洛196
在Go的io包中实现了多系统兼容的I/O包装到抽象功能的实现,虽然在操作时也使用的缓冲区,但是并没有针对缓冲区的操作进行相关的功能实现bufio包从包名就可以看出是一个提供了缓冲区版本的io包,在原有的io包的基础上进行进一步拓展了缓冲区的相关操作,提供了更精细的I/O操作bufio包是io包的拓展,在bufio包中,绝大多数的io包中的方法都被“继承”了下来,并拓展了新的方法默认缓冲区大小为64 * 1024字节读相关type Reader struct {}创建Reader NewReader(rd io.Reader) *Reader 根据一个io.Reader创建一个实现...

在Go的io包中实现了多系统兼容的I/O包装到抽象功能的实现,虽然在操作时也使用的缓冲区,但是并没有针对缓冲区的操作进行相关的功能实现

bufio包从包名就可以看出是一个提供了缓冲区版本的io包,在原有的io包的基础上进行进一步拓展了缓冲区的相关操作,提供了更精细的I/O操作

bufio包是io包的拓展,在bufio包中,绝大多数的io包中的方法都被“继承”了下来,并拓展了新的方法

默认缓冲区大小为64 * 1024字节

读相关

type Reader struct {}

创建Reader

NewReader(rd io.Reader) *Reader
    根据一个io.Reader创建一个实现了缓冲区操作的Reader
    使用默认大小的缓冲区

NewReaderSize(rd io.Reader, size int) *Reader
    指定缓冲区大小不小于size
    如果rd的缓冲区已经不小于指定的size,则返回rd
    否则会对rd的缓冲区进行扩大后返回

Reader的相关方法

Reset(r io.Reader)  :重设Reader的基础io.Reader
    会丢弃现有缓冲中的数据,并清除所有错误

Buffered() int :返回缓冲中现有的可读取的字节数

Peek(n int) ([]byte, error) :返回读取流的下n个字节,而不会移动读取位置
    返回的[]byte只在下一次调用读取操作前合法
    如果Peek返回的切片长度比n小,会返会一个错误说明原因

Read(p []byte) (n int, err error)
    调用下层Reader接口一次Read方法
    读取到达结尾时返回值n为0而err为io.EOF

ReadByte() (c byte, err error) :读取并返回一个字节。如果没有可用的数据,会返回错误

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

ReadLine() (line []byte, isPrefix bool, err error)
    尝试返回一行数据,不包含行尾的标志字节("\r\n"或"\n")
    返回值isPrefix会在成功返回该行最后一个片段时才设为false
    如果行太长超过了缓冲,isPrefix会被设为true,并返回当前部分,剩下的部分将在之后的调用中返回
    line和err两个返回值至少一个非nil
    如果输入流结束时没有行尾标志字节,正常返回且不会报错

ReadBytes(delim byte) (line []byte, err error)
    读取直到第一次遇到delim字节,返回读取到的数据(含最后的delim字节)切片
    如果在读取到delim之前遇到了错误,会返回在错误之前读取的数据以及该错误(一般是io.EOF)
    当且仅当返回的切片不以delim结尾时,会返回一个非nil的错误

ReadString(delim byte) (line string, err error): 和ReadBytes功能相同,返回读取的字节切片的字符串形式

WriteTo(w io.Writer) (n int64, err error)

写相关

type Writer struct {} :实现了给一个io.Writer接口对象附加缓冲区操作

创建Writer

NewWriter(w io.Writer) *Writer
    根据一个io.Writer创建一个实现了缓冲区操作的Writer
    使用默认大小的缓冲区

NewWriterSize(w io.Writer, size int) *Writer
    指定缓冲区大小不小于size
    如果w的缓冲区已经不小于指定的size,则返回w
    否则会对rd的缓冲区进行扩大后返回

Writer的相关方法

Reset(w io.Writer)  :重设Writer的基础io.Writer
    会丢弃现有缓冲中的数据,并清除所有错误

Buffered() int :返回缓冲中已使用的字节数。

Available() int  :返回缓冲中还有多少字节未使用

Write(p []byte) (nn int, err error) :写入p的内容到缓冲区,如果nn < len(p),会返回一个错误说明原因

WriteString(s string) (int, error) : 写入s字符串到缓冲区,如果nn < len(p),会返回一个错误说明原因

WriteByte(c byte) error :写入单个字节到缓冲区

WriteRune(r rune) (size int, err error) :写入一个unicode码的utf-8编码值到缓冲区

Flush() error :将缓冲中的数据写入下层的io.Writer接口

ReadFrom(r io.Reader) (n int64, err error)

读写结合类型

type ReadWriter struct {
    *Reader
    *Writer
}

创建ReadWriter

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

条件片段读取

type Scanner struct {} :每次读取时满足一定条件后暂停读取

创建Scanner

NewScanner(r io.Reader) *Scanner

SplitFunc函数类型

SplitFunc函数类型用来设定暂停读取的条件

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

data表示数据中尚未读取部分的符合条件的原始数据切片,atEOF表示是否读取到了末尾
advance表示下一次开始读取的位置应该基于当前读取位置前进的字节数
token表示将要返回的token切片

预设的SplitFunc类型函数

ScanBytes  :将每个字节作为一个token返回
ScanRunes  :将每个utf-8编码的unicode码值作为一个token返回
    错误的utf-8编码会翻译为U+FFFD = "\xef\xbf\xbd",但只会消耗一个字节
    调用者无法区分正确编码的rune和错误编码的rune
ScanWords  :将空白分隔的片段(去掉前后空白后)作为一个token返回
ScanLines  :将每一行文本去掉末尾的换行标记作为一个token返回
    返回的行可能是空字符串
    最后一行即使没有换行符也会作为一个token返回

Scanner的相关方法

Split(split SplitFunc) :设定暂停读取的条件函数
    SplitFunc函数类型用来设定暂停读取的条件
    默认值为bufio.ScanLines
    该方法必须在Scan()调用之前调用

Scan() bool
    将当前位置的token放到缓冲区
    并让Scanner的扫描位置移动到下一个位置(由SplitFunc返回的advance指定)
    当因为到达输入流结尾或遇到错误时返回false

Bytes() []byte  :返回最近一次Scan调用后生成并放置在缓冲区的token
Text() string   :返回最近一次Scan调用后生成并放置在缓冲区的token
Err() error     :返回Scanner在调用Scan()时遇到的第一个非EOF的错误


网址导航