ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
[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 } ```