bufio
最后更新于:2022-04-02 02:42:19
[TOC]
## 概述
- **bufio包实现了有缓冲的I/O**
- 它包装一个io.Reader或io.Writer接口对象,且同时还提供了缓冲和一些文本I/O的帮助函数的对象
## 语法
### Func
```
func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error)
func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error)
func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error)
func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error)
```
### Type
```
type Reader
func NewReader(rd io.Reader) *Reader
func NewReaderSize(rd io.Reader, size int) *Reader
func (b *Reader) Reset(r io.Reader)
func (b *Reader) Buffered() int // 返回缓冲中已使用的字节数
func (b *Reader) Peek(n int) ([]byte, error) // 只获取,不出栈
func (b *Reader) Discard(n int) (discarded int, err error) // 跳过 n 个字节
func (b *Reader) Read(p []byte) (n int, err error)
func (b *Reader) ReadByte() (c byte, err error) // 读取一个字节
func (b *Reader) UnreadByte() error // 吐出最近一次读取操作读取的最后一个字节。(只能吐出最后一个,多次调用会出问题)
func (b *Reader) ReadRune() (r rune, size int, err error)
func (b *Reader) UnreadRune() error
// ReadLine是一个低水平的行数据读取原语。大多数调用者应使用ReadBytes('\n')或ReadString('\n')代替,或者使用Scanner
func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error)
func (b *Reader) ReadSlice(delim byte) (line []byte, err error)
func (b *Reader) ReadBytes(delim byte) (line []byte, err error)
func (b *Reader) ReadString(delim byte) (line string, err error)
func (b *Reader) WriteTo(w io.Writer) (n int64, err error)
type Writer
func NewWriter(w io.Writer) *Writer
func NewWriterSize(w io.Writer, size int) *Writer
func (b *Writer) Reset(w io.Writer)
func (b *Writer) Buffered() int
func (b *Writer) Available() int //返回缓冲中还有多少字节未使用
func (b *Writer) Write(p []byte) (nn int, err error)
func (b *Writer) WriteString(s string) (int, error)
func (b *Writer) WriteByte(c byte) error
func (b *Writer) WriteRune(r rune) (size int, err error)
func (b *Writer) Flush() error
func (b *Writer) ReadFrom(r io.Reader) (n int64, err error)
type ReadWriter
func NewReadWriter(r *Reader, w *Writer) *ReadWriter
type Scanner
func NewScanner(r io.Reader) *Scanner
func (s *Scanner) Split(split SplitFunc)
func (s *Scanner) Scan() bool
func (s *Scanner) Bytes() []byte
func (s *Scanner) Text() string
func (s *Scanner) Err() error
```
## 实例
### bytes->Reader->带缓存的 Reader
```
```
### ReadBytes 截取到界定符
```
reader := bufio.NewReaderSize(strings.NewReader("http://studygolang.com.\nt It is the home of gophers"), 14)
s, _ := reader.ReadBytes('\n')
fmt.Println(string(s)) //h
```
### NewScanner 读取屏幕输入
```
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
fmt.Println(scanner.Text()) // Println will add back the final '\n'
}
if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, "reading standard input:", err)
}
```
### 进行分词
```
const input = "This is The Golang 你好 Standard Library.\nWelcome you!"
scanner := bufio.NewScanner(strings.NewReader(input))
//scanner.Split(bufio.ScanBytes) //单个词分词.不能分中文
//scanner.Split(bufio.ScanLines) //以行分词
//scanner.Split(bufio.ScanRunes) //以词分词,可分中文
scanner.Split(bufio.ScanWords) //以空格分词
count := 0
for scanner.Scan() {
fmt.Println(scanner.Text())
count++
}
if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, "reading input:", err)
}
fmt.Println(count)
// output:
//This
//is
//The
//Golang
//你好
//Standard
//Library.
//Welcome
//you!
//9
```
### 对 tcp 包进行切割
对tcp 进行拆包
```
scanner := bufio.NewScanner(t.conn)
scanner.Split(proto.Split)
for scanner.Scan() {
t.handleRead(scanner.Bytes())
}
// 假设对包的前4字节表示包的长度
func split(data []byte, atEOF bool) (advance int, token []byte, err error) {
var length uint32
if !atEOF {
_ = binary.Read(bytes.NewReader(data[:4]), binary.BigEndian, &length)
if length > 0 && len(data) >= int(length) {
return int(length), data[:length], nil
}
}
return
}
```
';