bufio
包实现了缓冲的 IO. 它包含分别实现 io.Reader()
和 io.Writer()
接口的 Reader
和 Writer
对象,提供了 IO 缓冲区和文本类型 IO 的一些支持.导入方式为 import "bufio"
常用类型定义 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 type Reader struct { } type Writer struct { } type ReadWriter struct { *Reader *Writer } type Scanner struct { } type SplitFunc func (data []byte , atEOF bool ) (advance int , token []byte , err error)
常用常量及变量 1 2 3 4 const ( MaxScanTokenSize = 64 * 1024 )
常用函数 bufio
包函数1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 func NewReader (rd io.Reader) *Reader func NewReaderSize (rd io.Reader, size int ) *Reader func NewWriter (w io.Writer) *Writer func NewWriterSize (w io.Writer, size int ) *Writer func NewReadWriter (r *Reader, w *Writer) *ReadWriter 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)
Reader
结构体方法1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 func (b *Reader) Reset (r io.Reader) func (b *Reader) Buffered () int func (b *Reader) Peek (n int ) ([]byte , error) func (b *Reader) Read (p []byte ) (n int , err error) func (b *Reader) ReadByte () (c byte , err error) func (b *Reader) ReadLine () (line []byte , isPrefix bool , 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)
Writer
结构体方法1 2 3 4 5 6 7 func (b *Writer) Reset (w io.Writer) // 丢弃缓冲中的数据,清除任何错误,将 b 设置为向 w 写入数据func (b *Writer) Buffered () int // 返回缓冲中现有的可写入的字节数func (b *Writer) Write (p []byte ) (nn int , err error) // 将 p 的内容写入缓冲.返回写入的字节数及可能发生的错误.如果 nn < len (p) ,err 不为空func (b *Writer) WriteString (s string ) (int , error) // 将 s 写入缓冲.返回写入的字节数及可能发生的错误.如果 nn < len (p) ,err 不为空func (b *Writer) WriteByte (c byte ) error // 将单个字节 c 写入缓冲,返回可能发生的错误func (b *Writer) Flush () error // 将缓冲区数据持久化到文件中.返回可能发生的错误func (b *Writer) ReadFrom (r io.Reader) (n int64 , err error) // 实现 `io .ReaderFrom ` 接口.从 r 中读取数据到缓冲区
Scanner
结构体方法1 2 3 4 5 6 7 8 9 10 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
示例 现有一文件 filename
内容如下:
1 2 3 hello the second line: nice to meet you the third line: see you next time
bufio
读写示例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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 import ( "bufio" "fmt" "io" "os" ) func WriterExample (bw *bufio.Writer) { defer bw.Flush() bw.WriteString("this new add line\n" ) } func ReadLineExample (br *bufio.Reader) { for { line, isPrefix, err := br.ReadLine() if err == io.EOF { break } if isPrefix { fmt.Printf("该行未结束,读到内容为: %v" , string (line)) } else { fmt.Printf("该行结束,读到或剩余内容为: %v" , string (line)) } fmt.Println() } } func ReadStringExample (br *bufio.Reader) { for { line, err := br.ReadString('\n' ) if err == io.EOF { fmt.Print(line) break } fmt.Print(line) } } func main () { file, err := os.OpenFile("filename" , os.O_RDWR|os.O_CREATE|os.O_APPEND, 0 ) if err != nil { fmt.Println("err" , err) return } defer file.Close() br := bufio.NewReaderSize(reader, 16 ) ReadLineExample(br) file.Seek(0 , 0 ) fmt.Println("------" ) ReadStringExample(br) file.Seek(0 , 0 ) bw := bufio.NewWriter(file) WriterExample(bw) }
通过以上示例可以看到:
ReadLine()
超过缓冲区大小的数据被分为多次读取,且行尾的换行符不被保留
文件增加 “this new add line\n” 内容
bufio.Scanner
扫描示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import ( "bufio" "fmt" "os" "strings" ) func main () { const input = "Now is the winter of our discontent,\nMade glorious summer by this sun of York.\n" scanner := bufio.NewScanner(strings.NewReader(input)) scanner.Split(bufio.ScanWords) count := 0 for scanner.Scan() { count++ } if err := scanner.Err(); err != nil { fmt.Fprintln(os.Stderr, "reading input:" , err) } fmt.Printf("%d\n" , count) }
如下示例尝试将分割分割的字符串转换为数字格式
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 import ( "bufio" "fmt" "strconv" "strings" ) func main () { const input = "1234 5678 5681 1234567890123456" scanner := bufio.NewScanner(strings.NewReader(input)) split := func (data []byte , atEOF bool ) (advance int , token []byte , err error) { advance, token, err = bufio.ScanWords(data, atEOF) if err == nil && token != nil { _, err = strconv.ParseInt(string (token), 10 , 32 ) } return } scanner.Split(split) for scanner.Scan() { fmt.Printf("%s\n" , scanner.Text()) } if err := scanner.Err(); err != nil { fmt.Printf("Invalid input: %s" , err) } }