日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Golang学习 - bufio 包

發布時間:2025/4/16 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Golang学习 - bufio 包 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
------------------------------------------------------------// bufio 包實現了帶緩存的 I/O 操作------------------------------------------------------------type Reader struct { ... }// NewReaderSize 將 rd 封裝成一個帶緩存的 bufio.Reader 對象, // 緩存大小由 size 指定(如果小于 16 則會被設置為 16)。 // 如果 rd 的基類型就是有足夠緩存的 bufio.Reader 類型,則直接將 // rd 轉換為基類型返回。 func NewReaderSize(rd io.Reader, size int) *Reader// NewReader 相當于 NewReaderSize(rd, 4096) func NewReader(rd io.Reader) *Reader// bufio.Reader 實現了如下接口: // io.Reader // io.WriterTo // io.ByteScanner // io.RuneScanner// Peek 返回緩存的一個切片,該切片引用緩存中前 n 個字節的數據, // 該操作不會將數據讀出,只是引用,引用的數據在下一次讀取操作之 // 前是有效的。如果切片長度小于 n,則返回一個錯誤信息說明原因。 // 如果 n 大于緩存的總大小,則返回 ErrBufferFull。 func (b *Reader) Peek(n int) ([]byte, error)// Read 從 b 中讀出數據到 p 中,返回讀出的字節數和遇到的錯誤。 // 如果緩存不為空,則只能讀出緩存中的數據,不會從底層 io.Reader // 中提取數據,如果緩存為空,則: // 1、len(p) >= 緩存大小,則跳過緩存,直接從底層 io.Reader 中讀 // 出到 p 中。 // 2、len(p) < 緩存大小,則先將數據從底層 io.Reader 中讀取到緩存 // 中,再從緩存讀取到 p 中。 func (b *Reader) Read(p []byte) (n int, err error)// Buffered 返回緩存中未讀取的數據的長度。 func (b *Reader) Buffered() int// Discard 跳過后續的 n 個字節的數據,返回跳過的字節數。 // 如果結果小于 n,將返回錯誤信息。 // 如果 n 小于緩存中的數據長度,則不會從底層提取數據。 func (b *Reader) Discard(n int) (discarded int, err error)// ReadSlice 在 b 中查找 delim 并返回 delim 及其之前的所有數據。 // 該操作會讀出數據,返回的切片是已讀出的數據的引用,切片中的數據 // 在下一次讀取操作之前是有效的。 // // 如果找到 delim,則返回查找結果,err 返回 nil。 // 如果未找到 delim,則: // 1、緩存不滿,則將緩存填滿后再次查找。 // 2、緩存是滿的,則返回整個緩存,err 返回 ErrBufferFull。 // // 如果未找到 delim 且遇到錯誤(通常是 io.EOF),則返回緩存中的所 // 有數據和遇到的錯誤。 // // 因為返回的數據有可能被下一次的讀寫操作修改,所以大多數操作應該 // 使用 ReadBytes 或 ReadString,它們返回的是數據的拷貝。 func (b *Reader) ReadSlice(delim byte) (line []byte, err error)// ReadLine 是一個低水平的行讀取原語,大多數情況下,應該使用 // ReadBytes('\n') 或 ReadString('\n'),或者使用一個 Scanner。 // // ReadLine 通過調用 ReadSlice 方法實現,返回的也是緩存的切片。用于 // 讀取一行數據,不包括行尾標記(\n 或 \r\n)。 // // 只要能讀出數據,err 就為 nil。如果沒有數據可讀,則 isPrefix 返回 // false,err 返回 io.EOF。 // // 如果找到行尾標記,則返回查找結果,isPrefix 返回 false。 // 如果未找到行尾標記,則: // 1、緩存不滿,則將緩存填滿后再次查找。 // 2、緩存是滿的,則返回整個緩存,isPrefix 返回 true。 // // 整個數據尾部“有一個換行標記”和“沒有換行標記”的讀取結果是一樣。 // // 如果 ReadLine 讀取到換行標記,則調用 UnreadByte 撤銷的是換行標記, // 而不是返回的數據。 func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error)// ReadBytes 功能同 ReadSlice,只不過返回的是緩存的拷貝。 func (b *Reader) ReadBytes(delim byte) (line []byte, err error)// ReadString 功能同 ReadBytes,只不過返回的是字符串。 func (b *Reader) ReadString(delim byte) (line string, err error)// Reset 將 b 的底層 Reader 重新指定為 r,同時丟棄緩存中的所有數據,復位 // 所有標記和錯誤信息。 bufio.Reader。 func (b *Reader) Reset(r io.Reader)------------------------------// 示例:Peek、Read、Discard、Buffered func main() {sr := strings.NewReader("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890")buf := bufio.NewReaderSize(sr, 0)b := make([]byte, 10)fmt.Println(buf.Buffered()) // 0s, _ := buf.Peek(5)s[0], s[1], s[2] = 'a', 'b', 'c'fmt.Printf("%d %q\n", buf.Buffered(), s) // 16 "abcDE"buf.Discard(1)for n, err := 0, error(nil); err == nil; {n, err = buf.Read(b)fmt.Printf("%d %q %v\n", buf.Buffered(), b[:n], err)}// 5 "bcDEFGHIJK" <nil>// 0 "LMNOP" <nil>// 6 "QRSTUVWXYZ" <nil>// 0 "123456" <nil>// 0 "7890" <nil>// 0 "" EOF }------------------------------// 示例:ReadLine func main() {sr := strings.NewReader("ABCDEFGHIJKLMNOPQRSTUVWXYZ\n1234567890")buf := bufio.NewReaderSize(sr, 0)for line, isPrefix, err := []byte{0}, false, error(nil); len(line) > 0 && err == nil; {line, isPrefix, err = buf.ReadLine()fmt.Printf("%q %t %v\n", line, isPrefix, err)}// "ABCDEFGHIJKLMNOP" true <nil>// "QRSTUVWXYZ" false <nil>// "1234567890" false <nil>// "" false EOFfmt.Println("----------")// 尾部有一個換行標記buf = bufio.NewReaderSize(strings.NewReader("ABCDEFG\n"), 0)for line, isPrefix, err := []byte{0}, false, error(nil); len(line) > 0 && err == nil; {line, isPrefix, err = buf.ReadLine()fmt.Printf("%q %t %v\n", line, isPrefix, err)}// "ABCDEFG" false <nil>// "" false EOFfmt.Println("----------")// 尾部沒有換行標記buf = bufio.NewReaderSize(strings.NewReader("ABCDEFG"), 0)for line, isPrefix, err := []byte{0}, false, error(nil); len(line) > 0 && err == nil; {line, isPrefix, err = buf.ReadLine()fmt.Printf("%q %t %v\n", line, isPrefix, err)}// "ABCDEFG" false <nil>// "" false EOF }------------------------------// 示例:ReadSlice func main() {// 尾部有換行標記buf := bufio.NewReaderSize(strings.NewReader("ABCDEFG\n"), 0)for line, err := []byte{0}, error(nil); len(line) > 0 && err == nil; {line, err = buf.ReadSlice('\n')fmt.Printf("%q %v\n", line, err)}// "ABCDEFG\n" <nil>// "" EOFfmt.Println("----------")// 尾部沒有換行標記buf = bufio.NewReaderSize(strings.NewReader("ABCDEFG"), 0)for line, err := []byte{0}, error(nil); len(line) > 0 && err == nil; {line, err = buf.ReadSlice('\n')fmt.Printf("%q %v\n", line, err)}// "ABCDEFG" EOF }------------------------------------------------------------type Writer struct { ... }// NewWriterSize 將 wr 封裝成一個帶緩存的 bufio.Writer 對象, // 緩存大小由 size 指定(如果小于 4096 則會被設置為 4096)。 // 如果 wr 的基類型就是有足夠緩存的 bufio.Writer 類型,則直接將 // wr 轉換為基類型返回。 func NewWriterSize(wr io.Writer, size int) *Writer// NewWriter 相當于 NewWriterSize(wr, 4096) func NewWriter(wr io.Writer) *Writer// bufio.Writer 實現了如下接口: // io.Writer // io.ReaderFrom // io.ByteWriter// WriteString 功能同 Write,只不過寫入的是字符串 func (b *Writer) WriteString(s string) (int, error)// WriteRune 向 b 寫入 r 的 UTF-8 編碼,返回 r 的編碼長度。 func (b *Writer) WriteRune(r rune) (size int, err error)// Flush 將緩存中的數據提交到底層的 io.Writer 中 func (b *Writer) Flush() error// Available 返回緩存中未使用的空間的長度 func (b *Writer) Available() int// Buffered 返回緩存中未提交的數據的長度 func (b *Writer) Buffered() int// Reset 將 b 的底層 Writer 重新指定為 w,同時丟棄緩存中的所有數據,復位 // 所有標記和錯誤信息。相當于創建了一個新的 bufio.Writer。 func (b *Writer) Reset(w io.Writer)------------------------------// 示例:Available、Buffered、WriteString、Flush func main() {buf := bufio.NewWriterSize(os.Stdout, 0)fmt.Println(buf.Available(), buf.Buffered()) // 4096 0buf.WriteString("ABCDEFGHIJKLMNOPQRSTUVWXYZ")fmt.Println(buf.Available(), buf.Buffered()) // 4070 26// 緩存后統一輸出,避免終端頻繁刷新,影響速度buf.Flush() // ABCDEFGHIJKLMNOPQRSTUVWXYZ }------------------------------------------------------------// ReadWriter 集成了 bufio.Reader 和 bufio.Writer type ReadWriter struct {*Reader*Writer }// NewReadWriter 將 r 和 w 封裝成一個 bufio.ReadWriter 對象 func NewReadWriter(r *Reader, w *Writer) *ReadWriter------------------------------------------------------------// Scanner 提供了一個方便的接口來讀取數據,例如遍歷多行文本中的行。Scan 方法會通過 // 一個“匹配函數”讀取數據中符合要求的部分,跳過不符合要求的部分。“匹配函數”由調 // 用者指定。本包中提供的匹配函數有“行匹配函數”、“字節匹配函數”、“字符匹配函數” // 和“單詞匹配函數”,用戶也可以自定義“匹配函數”。默認的“匹配函數”為“行匹配函 // 數”,用于獲取數據中的一行內容(不包括行尾標記) // // Scanner 使用了緩存,所以匹配部分的長度不能超出緩存的容量。默認緩存容量為 4096 - // bufio.MaxScanTokenSize,用戶可以通過 Buffer 方法指定自定義緩存及其最大容量。 // // Scan 在遇到下面的情況時會終止掃描并返回 false(掃描一旦終止,將無法再繼續): // 1、遇到 io.EOF // 2、遇到讀寫錯誤 // 3、“匹配部分”的長度超過了緩存的長度 // // 如果需要對錯誤進行更多的控制,或“匹配部分”超出緩存容量,或需要連續掃描,則應該 // 使用 bufio.Reader type Scanner struct { ... }// NewScanner 創建一個 Scanner 來掃描 r,默認匹配函數為 ScanLines。 func NewScanner(r io.Reader) *Scanner// Buffer 用于設置自定義緩存及其可擴展范圍,如果 max 小于 len(buf),則 buf 的尺寸將 // 固定不可調。Buffer 必須在第一次 Scan 之前設置,否則會引發 panic。 // 默認情況下,Scanner 會使用一個 4096 - bufio.MaxScanTokenSize 大小的內部緩存。 func (s *Scanner) Buffer(buf []byte, max int)// Split 用于設置“匹配函數”,這個函數必須在調用 Scan 前執行。 func (s *Scanner) Split(split SplitFunc)// SplitFunc 用來定義“匹配函數”,data 是緩存中的數據。atEOF 標記數據是否讀完。 // advance 返回 data 中已處理的數據的長度。token 返回找到的“匹配部分”,“匹配 // 部分”可以是緩存的切片,也可以是自己新建的數據(比如 bufio.errorRune)。“匹 // 配部分”將在 Scan 之后通過 Bytes 和 Text 反饋給用戶。err 返回錯誤信息。 // // 如果在 data 中無法找到一個完整的“匹配部分”則應返回 (0, nil, nil),以便告訴 // Scanner 向緩存中填充更多數據,然后再次掃描(Scan 會自動重新掃描)。如果緩存已 // 經達到最大容量還沒有找到,則 Scan 會終止并返回 false。 // 如果 data 為空,則“匹配函數”將不會被調用,意思是在“匹配函數”中不必考慮 // data 為空的情況。 // // 如果 err != nil,掃描將終止,如果 err == ErrFinalToken,則 Scan 將返回 true, // 表示掃描正常結束,如果 err 是其它錯誤,則 Scan 將返回 false,表示掃描出錯。錯誤 // 信息可以在 Scan 之后通過 Err 方法獲取。 // // SplitFunc 的作用很簡單,從 data 中找出你感興趣的數據,然后返回,同時返回已經處理 // 的數據的長度。 type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error)// Scan 開始一次掃描過程,如果匹配成功,可以通過 Bytes() 或 Text() 方法取出結果, // 如果遇到錯誤,則終止掃描,并返回 false。 func (s *Scanner) Scan() bool// Bytes 將最后一次掃描出的“匹配部分”作為一個切片引用返回,下一次的 Scan 操作會覆 // 蓋本次引用的內容。 func (s *Scanner) Bytes() []byte// Text 將最后一次掃描出的“匹配部分”作為字符串返回(返回副本)。 func (s *Scanner) Text() string// Err 返回掃描過程中遇到的非 EOF 錯誤,供用戶調用,以便獲取錯誤信息。 func (s *Scanner) Err() error// ScanBytes 是一個“匹配函數”用來找出 data 中的單個字節并返回。 func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error)// ScanRunes 是一個“匹配函數”,用來找出 data 中單個 UTF8 字符的編碼。如果 UTF8 編 // 碼錯誤,則 token 會返回 "\xef\xbf\xbd"(即:U+FFFD),但只消耗 data 中的一個字節。 // 這使得調用者無法區分“真正的U+FFFD字符”和“解碼錯誤的返回值”。 func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error)// ScanLines 是一個“匹配函數”,用來找出 data 中的單行數據并返回(包括空行)。 // 行尾標記可以是 \n 或 \r\n(返回值不包含行尾標記) func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error)// ScanWords 是一個“匹配函數”,用來找出 data 中以空白字符分隔的單詞。 // 空白字符由 unicode.IsSpace 定義。 func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error)------------------------------// 示例:掃描 func main() {// 逗號分隔的字符串,最后一項為空const input = "1,2,3,4,"scanner := bufio.NewScanner(strings.NewReader(input))// 定義匹配函數(查找逗號分隔的字符串)onComma := func(data []byte, atEOF bool) (advance int, token []byte, err error) {for i := 0; i < len(data); i++ {if data[i] == ',' {return i + 1, data[:i], nil}}if atEOF {// 告訴 Scanner 掃描結束。return 0, data, bufio.ErrFinalToken} else {// 告訴 Scanner 沒找到匹配項,讓 Scan 填充緩存后再次掃描。return 0, nil, nil}}// 指定匹配函數scanner.Split(onComma)// 開始掃描for scanner.Scan() {fmt.Printf("%q ", scanner.Text())}// 檢查是否因為遇到錯誤而結束if err := scanner.Err(); err != nil {fmt.Fprintln(os.Stderr, "reading input:", err)} }------------------------------// 示例:帶檢查掃描 func main() {const input = "1234 5678 1234567901234567890 90"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 0, nil, nil 的情況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)} }------------------------------------------------------------

轉載于:https://www.cnblogs.com/golove/p/3282667.html

總結

以上是生活随笔為你收集整理的Golang学习 - bufio 包的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。