(整理自https://studygolang.com/articles/4367)

Read类

func NewReaderSize(rd io.Reader, size int) *Reader
NewReadSize()将rd封装成一个拥有size大小缓存的bufio.Reader对象。
func NewReader(rd io.Reader) *Reader
NewReader()相当于NewReaderSize(rd, 4096)。

Peek()

Peek()返回缓存的一个切片,该切片引用缓存中前n字节数据。该操作不会将数据读出,只是引用。通过 Peek 的返回值,可以修改缓存中的数据,但是不能修改底层 io.Reader 中的数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
s := strings.NewReader("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890")
br := bufio.NewReaderSize(s, 1)
b, _ := br.Peek(5)
fmt.Printf("%s\n", b)
b, _ = br.Peek(5)
fmt.Printf("%s\n", b)
b[0] = 'a'
b, _ = br.Peek(5)
fmt.Printf("%s\n", b)
fmt.Println(s)
}

输出:

1
2
3
4
ABCDE
ABCDE
aBCDE
&{ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 16 -1}

Read()

func (b *Reader) Read(p []byte) (n int, err error)
Read()从b中读出数据到p中,返回读出的字节数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
s := strings.NewReader("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890")
br := bufio.NewReader(s)
b := make([]byte, 20)
c := make([]byte, 18)
n, _ := br.Read(b)
fmt.Println(n)
fmt.Printf("%s\n", b)
n, _ = br.Read(c)
fmt.Println(n)
fmt.Printf("%s\n", c)
}

输出:

1
2
3
4
20
ABCDEFGHIJKLMNOPQRST
16
UVWXYZ1234567890

ReadByte() UnReadByte()

func (b *Reader) ReadByte() (c byte, err error)
ReadByte()从b中读出一个字节并返回。
func (b *Reader) UnreadByte() error
UnreadByte 撤消最后一次读出的字节,只有最后读出的字节可以被撤消。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
s := strings.NewReader("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890")
br := bufio.NewReader(s)
c, _ := br.ReadByte()
fmt.Printf("%c\n", c)
c, _ = br.ReadByte()
fmt.Printf("%c\n", c)
br.UnreadByte()
c, _ = br.ReadByte()
fmt.Printf("%c\n", c)
}

输出:

1
2
3
A
B
B

ReadRune(), UnreadRune()

func (b *Reader) ReadRune() (r rune, size int, err error)
ReadRune()从b中读出一个UTF8编码的字符并返回,同时返回该字符的UTF8编码长度。如果UTF8序列无法解码出一个正确的Unicode字符, 则只读出b中的一个字节。
func (b *Reader) UnreadRune() error
UnreadRune()撤消最后一次读出的 Unicode 字符。(感觉汉字的UnreadRune()存在问题)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
s := strings.NewReader("A字母")
br := bufio.NewReader(s)
c, size, _ := br.ReadRune()
fmt.Printf("%c %d\n", c, size)
br.UnreadByte()
c, size, _ = br.ReadRune()
fmt.Printf("%c %d\n", c, size)
c, size, _ = br.ReadRune()
fmt.Printf("%c %d\n", c, size)
br.UnreadByte()
c, size, _ = br.ReadRune()
fmt.Printf("%c %d\n", c, size)
}

输出:

1
2
3
4
A 1
A 1
字 3
� 1

Buffered()

func (b *Reader) Buffered() int
Buffered()返回缓存中数据的长度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
s := strings.NewReader("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890")
br := bufio.NewReader(s)
fmt.Println(br.Buffered())
b, _ := br.Peek(1)
fmt.Printf("%s\n", b)
fmt.Println(br.Buffered())
c, _ := br.ReadByte()
fmt.Printf("%c\n", c)
fmt.Println(br.Buffered())
}

输出:

1
2
3
4
5
0
A
36
A
35

可以看出,在发生读动作后,br中才有缓存。在调用ReadByte()之后,缓存的数据会减少。

ReadSlice()

func (b *Reader) ReadSlice(delim byte) (line []byte, err error)
ReadSlice在b中查找delim并返回delim及其之前的所有数据的切片,该操作会读出数据,返回的切片是已读出数据的引用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
s := strings.NewReader("ABCD EFGHI JKLMNOPQRSTUVWXYZ1234567890")
br := bufio.NewReader(s)
w, _ := br.ReadSlice(' ')
fmt.Printf("%q\n", w) //%q表示带引号打印
fmt.Println(br.Buffered())
w, _ = br.ReadSlice(' ')
fmt.Printf("%q\n", w) //%q表示带引号打印
fmt.Println(br.Buffered())
}

输出:

1
2
3
4
"ABCD "
33
"EFGHI "
27

ReadLine()

func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error)
ReadLine()是一个低级的原始的行读取操作。大多数情况下,应该使用ReadBytes(‘\n’)或ReadString(‘\n’)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
s := strings.NewReader("ABCD\nEFGHI\nJKLMNOPQRSTUVWXYZ1234567890")
br := bufio.NewReader(s)
w, isPrefix, _ := br.ReadLine()
fmt.Printf("%q %v\n", w, isPrefix) //%q表示带引号打印
w, isPrefix, _ = br.ReadLine()
fmt.Printf("%q %v\n", w, isPrefix) //%q表示带引号打印
w, isPrefix, _ = br.ReadLine()
fmt.Printf("%q %v\n", w, isPrefix) //%q表示带引号打印
}

输出:

1
2
3
"ABCD" false
"EFGHI" false
"JKLMNOPQRSTUVWXYZ1234567890" false

ReadBytes()

func (b *Reader) ReadBytes(delim byte) (line []byte, err error)
ReadBytes()在b中查找delim并读出delim及其之前的所有数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
s := strings.NewReader("ABCD\nEFGHI\nJKLMNOPQRSTUVWXYZ1234567890")
br := bufio.NewReader(s)
w, _ := br.ReadBytes('\n')
fmt.Printf("%q\n", w) //%q表示带引号打印
w, _ = br.ReadBytes('\n')
fmt.Printf("%q\n", w) //%q表示带引号打印
w, _ = br.ReadBytes('\n')
fmt.Printf("%q\n", w) //%q表示带引号打印
}

输出:

1
2
3
"ABCD\n"
"EFGHI\n"
"JKLMNOPQRSTUVWXYZ1234567890"

ReadString()

func (b *Reader) ReadString(delim byte) (line string, err error)
ReadString()功能同ReadBytes()。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
s := strings.NewReader("ABCD\nEFGHI\nJKLMNOPQRSTUVWXYZ1234567890")
br := bufio.NewReader(s)
w, _ := br.ReadString('\n')
fmt.Printf("%q\n", w) //%q表示带引号打印
w, _ = br.ReadString('\n')
fmt.Printf("%q\n", w) //%q表示带引号打印
w, _ = br.ReadString('\n')
fmt.Printf("%q\n", w) //%q表示带引号打印
}

输出:

1
2
3
"ABCD\n"
"EFGHI\n"
"JKLMNOPQRSTUVWXYZ1234567890"

Reset()

func (b *Reader) Reset(r io.Reader)
Reset()丢弃任何的缓存数据,清除所有状态并将缓存读切换到r。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
s := strings.NewReader("ABCEFG")
str := strings.NewReader("123455")
br := bufio.NewReader(s)
b, _ := br.ReadString('\n')
fmt.Println(b) //ABCEFG
br.Reset(str)
b, _ = br.ReadString('\n')
fmt.Println(b) //123455
}

输出:

1
2
ABCEFG
123455

Writer类

func NewWriterSize(wr io.Writer, size int) *Writer
NewWriterSize()将wr封装成一个拥有size大小缓存的bufio.Writer对象。
func NewWriter(wr io.Writer) *Writer
NewWriter()相当于NewWriteSize(wr, 4096)。

Writer常用的方法有:
func (b *Writer) Flush() error
Flush()将缓存中的数据提交到底层的io.Writer中。

func (b *Writer) Available() int
Available()返回缓存中的可用空间。

func (b *Writer) Buffered() int
Buffered()返回缓存中未提交的数据长度。

Write(), WriteString()

func (b *Writer) Write(p []byte) (nn int, err error)
Write()将p中的数据写入b中,返回写入的字节数。

func (b *Writer) WriteString(s string) (int, error)
WriteString()同Write,只不过写入的是字符串。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package main
import (
"bufio"
"bytes"
"fmt"
)
func main() {
b := bytes.NewBuffer(make([]byte, 0))
bw := bufio.NewWriter(b)
fmt.Println(bw.Available()) // 4096
fmt.Println(bw.Buffered()) // 0
bw.WriteString("ABCDEFGH")
fmt.Println(bw.Available()) // 4088
fmt.Println(bw.Buffered()) // 8
fmt.Printf("%q\n", b) // ""
bw.Flush()
fmt.Println(bw.Available()) // 4096
fmt.Println(bw.Buffered()) // 0
fmt.Printf("%q\n", b) // "ABCEFG"
}

输出:

1
2
3
4
5
6
7
8
4096
0
4088
8
""
4096
0
"ABCDEFGH"

WriteByte(), WriteRune()

func (b *Writer) WriteByte(c byte) error
WriteByte()向b中写入一个字节。

func (b *Writer) WriteRune(r rune) (size int, err error)
WriteRune()向b中写入r的UTF8编码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package main
import (
"bufio"
"bytes"
"fmt"
)
func main() {
b := bytes.NewBuffer(make([]byte, 0))
bw := bufio.NewWriter(b)
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.Println(b) // Hello 世界!
}

输出:

1
Hello 世界!

ReadFrom()

func (b *Writer) ReadFrom(r io.Reader) (n int64, err error)
ReadFrom从r中读取数据进行缓存。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main
import (
"bufio"
"bytes"
"fmt"
"strings"
)
func main() {
b := bytes.NewBuffer(make([]byte, 0))
s := strings.NewReader("Hello 世界!")
bw := bufio.NewWriter(b)
bw.ReadFrom(s)
//bw.Flush() //ReadFrom无需使用Flush,其自己已经写入.
fmt.Println(b) // Hello 世界!
}

输出:

1
Hello 世界!

Reset()

func (b *Writer) Reset(w io.Writer)
Reset()丢弃任何没有写入的缓存数据,清除任何错误并且重新将b指定它的输出结果指向w。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main
import (
"bufio"
"bytes"
"fmt"
)
func main() {
b := bytes.NewBuffer(make([]byte, 0))
bw := bufio.NewWriter(b)
bw.WriteString("123")
c := bytes.NewBuffer(make([]byte, 0))
bw.Reset(c)
bw.WriteString("456")
bw.Flush()
fmt.Printf("%s\n", b)
fmt.Printf("%s\n", c)
}

输出:

1
2
456

ReadWriter类

func NewReadWriter(r *Reader, w *Writer) *ReadWriter
NewReadWriter()封装r和w为一个bufio.ReadWriter对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main
import (
"bufio"
"bytes"
"fmt"
"strings"
)
func main() {
b := bytes.NewBuffer(make([]byte, 0))
bw := bufio.NewWriter(b)
s := strings.NewReader("123")
br := bufio.NewReader(s)
rw := bufio.NewReadWriter(br, bw)
p, _ := rw.ReadString('\n')
fmt.Println(string(p)) //123
rw.WriteString("asdf")
rw.Flush()
fmt.Println(b) //asdf
}

输出:

1
2
123
asdf

Scanner

func NewScanner(r io.Reader) *Scanner
Scanner提供了一个方便的接口来读取数据。

Bytes(), Text()

func (s *Scanner) Bytes() []byte
Bytes()将最后一次扫描出的“指定部分”作为一个切掉返回(引用传递)。
func (s *Scanner) Text() string
Text()将最后一次扫描出的“指定部分”作为字符串返回(值传递)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
s := strings.NewReader("ABC\nDEF\r\nGHI\nJKL")
bs := bufio.NewScanner(s)
for bs.Scan() {
fmt.Printf("%s %v\n", bs.Bytes(), bs.Text())
}
}

输出:

1
2
3
4
ABC ABC
DEF DEF
GHI GHI
JKL JKL

Split()

func (s *Scanner) Split(split SplitFunc)
Split()用于设置Scanner的“切分函数”。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
s := strings.NewReader("ABC DEF GHI JKL")
bs := bufio.NewScanner(s)
bs.Split(bufio.ScanWords)
for bs.Scan() {
fmt.Println(bs.Text())
}
}

输出:

1
2
3
4
ABC
DEF
GHI
JKL

其中ScanWords是一个“切分函数”,用来找出data中的单词。类似的“切分函数”还有:ScanBytes, 用来data中的单个字节并返回;ScanRunes(), 用来找出data中的单个UTF8字符的编码并返回。 ScanLines, 用来找出data中的单行数据并返回(包括空行)。