bufio
bufio 实现了有缓冲的 I/O ,它包装一个 io.Reader 或 io.Writer 接口对象,创建另一个接口也实现了该接口,且同时还提供了缓冲和一些文本 I/O 的帮助函数对象
常量
const {
defaultBufSize = 4096 // 默认的缓冲区大小
}
变量
var (
ErrInvalidUnreadByte = errors.New("bufio: invalid use of UnreadByte")
ErrInvalidUnreadRune = errors.New("bufio: invalid use of UnreadRund")
ErrBufferFull = errors.New("bufio: buffer full") // 缓冲区满了
ErrNegativeCount = errors.New("bufio: negative count") // 缓冲区的大小为负数
)
- 错误信息
var (
ErrTooLong = errors.New("bufio.Scanner: token too long")
ErrNegativeAdvance = errors.New("bufio.Scanner: SplitFunc returns negative advance count")
ErrAdvanceTooFar = errors.New("bufio.Scanner: SplitFunc returns negative count beyond")
)
会被
Scanner类型返回的错误
读相关操作NewReader
NewReader
// 读取文件与strings.NewReader
func test1() {
// r := strings.NewReader("hello world")
f, _ := os.Open("test.txt")
defer f.Close()
// 也可以读取strings.NewReader中的内容
r2 := bufio.NewReader(f)
s, _ := r2.ReadString('\n')
fmt.Printf("s: %v\n", s)
}
// 控制每次读取的数量
func test2() {
s := strings.NewReader("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890")
br := bufio.NewReader(s)
p := make([]byte, 10) // 每次读取10个
for {
n, err := br.Read(p)
if err == io.EOF { // 读取完毕 退出
break
} else {
fmt.Printf("string(p[0:n]): %v\n", string(p[0:n]))
}
}
}
ReadByte
// 读取与回溯
func test3() {
s := strings.NewReader("ABCDEFG")
br := bufio.NewReader(s)
c, _ := br.ReadByte() // 读取一个字节
fmt.Printf("c: %c\n", c) // A
c, _ = br.ReadByte() // 读取一个
fmt.Printf("c: %c\n", c) // B
br.UnreadByte() // 吐出一个
c, _ = br.ReadByte() // 读取一个
fmt.Printf("c: %c\n", c) // B
}
ReadBytes
// 读取一个切片
func test6() {
s := strings.NewReader("ABC DEF GHI JKL")
br := bufio.NewReader(s)
// 读取通过空格分割的切片
w, _ := br.ReadBytes(' ')
fmt.Printf("w: %c\n", w) // w: [A B C ]
w, _ = br.ReadBytes(' ')
fmt.Printf("w: %c\n", w) // w: [D E F ]
w, _ = br.ReadBytes(' ') // %q 会输出为字符串
fmt.Printf("w: %q\n", w) // w: "GHI "
w, _ = br.ReadBytes(' ')
fmt.Printf("w: %c\n", w) // w: [J K L]
}
ReadRune
// 读取中文、日文等
func test4() {
s := strings.NewReader("你好,世界")
br := bufio.NewReader(s)
d, size, _ := br.ReadRune()
fmt.Printf("d: %c size: %v\n", d, size)
d, size, _ = br.ReadRune()
fmt.Printf("d: %c size: %v\n", d, size)
}
ReadLine
// 读取一行
func test5() {
s := strings.NewReader("ABC\nDEF\r\nGHI\r\nGHI")
br := bufio.NewReader(s)
line, isPrefix, _ := br.ReadLine()
// 如果字符超过了4096 那么说明我们拿到的是一个前缀 isPrefix 为 true
fmt.Printf("line: %q isPrefix: %v\n", line, isPrefix) // line: "ABC" isPrefix: false
line, isPrefix, _ = br.ReadLine()
fmt.Printf("line: %q isPrefix: %v\n", line, isPrefix)
line, isPrefix, _ = br.ReadLine()
fmt.Printf("line: %q isPrefix: %v\n", line, isPrefix)
line, isPrefix, _ = br.ReadLine()
fmt.Printf("line: %q isPrefix: %v\n", line, isPrefix)
}
ReadString
// 读取字符串
func test7() {
s := strings.NewReader("ABC DEF GHI JKL")
br := bufio.NewReader(s)
w, _ := br.ReadString(' ')
fmt.Printf("w: %q\n", w) // w: "ABC "
w, _ = br.ReadString(' ')
fmt.Printf("w: %q\n", w) // w: "DEF "
w, _ = br.ReadString(' ')
fmt.Printf("w: %q\n", w) // w: "GHI "
w, _ = br.ReadString(' ')
fmt.Printf("w: %q\n", w) // w: "JKL"
}
WriteTo
// 写内容到缓冲区/文件中
func test8() {
s := strings.NewReader("ABCDEFGHIJKLMN")
br := bufio.NewReader(s)
// 缓冲区
// b := bytes.NewBuffer(make([]byte, 0))
// br.WriteTo(b)
// fmt.Printf("b: %s\n", b)
// 也可以写到文件中 会覆盖前对应的位置 后面的不覆盖
f, _ := os.OpenFile("test.txt", os.O_RDWR, 0777)
br.WriteTo(f)
}
写相关操作 NewWriter
WriteString
func test9() {
f, _ := os.OpenFile("test.txt", os.O_RDWR, 0777) // File Reader Writer
defer f.Close()
// 如果写入的是一个视频会更高效 因为有缓冲区的功能 会覆盖前对应的位置 后面的不覆盖
w := bufio.NewWriter(f)
w.WriteString("hello golang")
w.Flush() // 刷新一下缓冲区 不然内容还在缓冲区里面 没写到文件中
}
Reset
func test10() {
b := bytes.NewBuffer(make([]byte, 0))
// 把b放入缓冲区
bw := bufio.NewWriter(b)
// 给缓冲区中写入数据
bw.WriteString("123456789")
c := bytes.NewBuffer(make([]byte, 0))
// 重置缓冲区为c
bw.Reset(c)
bw.WriteString("abc")
bw.Flush() // 刷新一下缓冲区 不然内容还在缓冲区里面 没写到文件中
fmt.Println(b) // 空 因为在重置缓冲区为c之前没有刷新 数据没写到b中
fmt.Println(c) // abc
}
Available与Buffered
func test11() {
b := bytes.NewBuffer(make([]byte, 0))
bw := bufio.NewWriter(b)
fmt.Printf("bw.Available(): %v\n", bw.Available()) // 4096默认缓冲区大小
fmt.Printf("bw.Buffered(): %v\n", bw.Buffered()) // 0
bw.WriteString("ABCDEFGHIJKLMN")
fmt.Printf("bw.Available(): %v\n", bw.Available()) // 4082 缓冲区剩余大小
fmt.Printf("bw.Buffered(): %v\n", bw.Buffered()) // 14 写入缓冲区大小
fmt.Printf("b: %v\n", b)
bw.Flush()
fmt.Printf("bw.Available(): %v\n", bw.Available()) // 4096
fmt.Printf("bw.Buffered(): %v\n", bw.Buffered()) // 0
}
WriteByte与WriteRune
func test12() {
b := bytes.NewBuffer(make([]byte, 0))
bw := bufio.NewWriter(b)
// 写入缓存 一个一个写 byte等同于int8
bw.WriteByte('H')
bw.WriteByte('e')
bw.WriteByte('l')
bw.WriteByte('l')
bw.WriteByte('o')
bw.WriteByte(' ')
bw.WriteRune('世')
bw.WriteRune('界')
bw.WriteRune('!')
bw.Flush()
fmt.Printf("b: %v\n", b)
}
读和写 ReadWriter
func test13() {
// 缓冲区 用来存储 作为bw的参数
b := bytes.NewBuffer(make([]byte, 0))
bw := bufio.NewWriter(b)
// 数据 用来给br读取 作为br参数
s := strings.NewReader("123")
br := bufio.NewReader(s)
// br bw Reader Writer作为参数
rw := bufio.NewReadWriter(br, bw)
// 读取到br读取的内容 也就是s
p, _ := rw.ReadString('\n')
fmt.Printf("p: %v\n", p) // p: 123
// 写入到bw的缓冲区 也就是b
rw.WriteString("abcd")
rw.Flush()
fmt.Println(b) // abcd
}
Scanner
Split与ScanWords
func test14() {
s := strings.NewReader("ABC DEF GHI JKL")
bs := bufio.NewScanner(s)
// 通过空格来分割
bs.Split(bufio.ScanWords)
// 每次调用 input.Scan(),即读入下一行,并移除行末的换行符;读取的内容可以调用 input.Text() 得到。Scan 函数在读到一行时返回 true,不再有输入时返回 false
for bs.Scan() {
fmt.Printf("bs.Text(): %v\n", bs.Text())
}
}
/*
bs.Text(): ABC
bs.Text(): DEF
bs.Text(): GHI
bs.Text(): JKL
*/
ScanBytes与ScanRunes
func test15() {
s := strings.NewReader("Hello 世界!")
bs := bufio.NewScanner(s)
// bs.Split(bufio.ScanBytes)
// 使用ScanRunes 不然中文会乱码
bs.Split(bufio.ScanRunes)
for bs.Scan() {
fmt.Printf("bs.Text(): %s\n", bs.Text())
}
}
/*
bs.Text(): H
bs.Text(): e
bs.Text(): l
bs.Text(): l
bs.Text(): o
bs.Text():
bs.Text(): 世
bs.Text(): 界
bs.Text(): !
*/