天天看點

Golang 中的 bufio 包詳解(五):常用函數

作者:路多辛

Golang 中的 bufio 包是帶緩沖 I/O 操作的标準庫,之前的幾篇文章詳細講解了 bufio.Reader、bufio.Writer 和 bufio.Scanner 這個幾個結構體的使用方法、特性和使用場景,本文介紹一下 bufio 包中的函數。

介紹常用函數之前,先簡單介紹下另一個結構體類型和一個函數類型:bufio.ReadWriter 和 bufio.SplitFunc,對應的定義如下:

type ReadWriter struct {
	*Reader
	*Writer
}

type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error)           

ReadWriter 結構體實作了 io.ReadWriter 接口,SplitFunc 是用來指定自定義分割規則的函數類型,通常結合 bufio.Scanner 使用。

建立對象函數

  • func NewReader(rd io.Reader) *Reader,建立一個帶緩沖的 Reader 對象。
  • func NewWriter(w io.Writer) *Writer,建立一個帶緩沖的 Writer 對象。
  • func NewReadWriter(r *Reader, w *Writer) *ReadWriter,建立一個帶緩沖的 ReadWriter 對象。
  • func NewReaderSize(rd io.Reader, size int) *Reader,建立一個帶緩沖的 Reader 對象,使用 size 指定緩沖區的最小值。
  • func NewWriterSize(w io.Writer, size int) *Writer,建立一個帶緩沖的 Writer 對象,使用 size 指定緩沖區的最小值。
  • func NewScanner(r io.Reader) *Scanner,建立一個帶緩沖的 Scanner 對象。

SplitFunc 類型函數

以下幾個函數都是 SplitFunc 類型,通常與 bufio.NewScanner 一起使用。

  • func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error),用于逐行讀取輸入流中的資料。
  • func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error),用于逐個位元組讀取輸入流中的資料。
  • func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error),用于逐個 unicode 編碼讀取輸入流中的資料。
  • func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error),用于逐個單詞(空格分割)讀取輸入流中的資料。

使用示例

package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"
)

func main() {
	// 确定讀取檔案的路徑
	path := "file.txt"

	// 打開檔案并處理錯誤
	file, err := os.Open(path)
	if err != nil {
		panic(err)
	}
	defer file.Close()

	// 建立Scanner類型對象
	scanner := bufio.NewScanner(file)

	// 設定分割函數
	scanner.Split(bufio.ScanWords)

	// 建立一個map對象,用于存儲單詞出現的次數
	counts := make(map[string]int)

	// 讀取檔案内容并統計單詞出現次數
	for scanner.Scan() {
		word := strings.ToLower(scanner.Text())
		counts[word]++
	}

	// 檢查Scanner是否出錯
	if err := scanner.Err(); err != nil {
		panic(err)
	}

	// 輸出結果到控制台
	for word, count := range counts {
		fmt.Printf("%s: %d\n", word, count)
	}

	// 讓使用者根據輸入的關鍵字進行篩選
	fmt.Print("Enter keyword to filter results: ")
	reader := bufio.NewReader(os.Stdin)
	input, _ := reader.ReadString('\n')
	keyword := strings.TrimSpace(input)

	if keyword != "" {
		for word, count := range counts {
			if strings.Contains(word, keyword) {
				fmt.Printf("%s: %d\n", word, count)
			}
		}
	}
}           

首先建立了一個 Scanner 類型的對象,指定了 ScanWords 作為分隔函數,然後周遊檔案内容,統計單詞出現的次數并将結果存儲到一個map中,最後讓使用者輸入關鍵字進行篩選,根據關鍵字過濾并輸出結果。

小結

bufio 是一個提供了帶緩沖讀寫操作的包,通過使用 bufio 包提供的類型和方法,可以高效地讀寫資料,特别是當涉及到大量資料的讀寫時,可以大大提高程式的性能。

繼續閱讀