bufio 把多次小 I/O 合併成一次大 I/O,大幅降低系統呼叫成本。
緩衝讀取#
import "bufio"
file, _ := os.Open("large_file.txt")
reader := bufio.NewReader(file)
// 按行讀取
for {
line, err := reader.ReadString('\n')
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
fmt.Print(line)
}
// 或使用 Scanner(更簡潔)
file.Seek(0, 0)
scanner := bufio.NewScanner(file)
for scanner.Scan() {
fmt.Println(scanner.Text())
}緩衝寫入#
file, _ := os.Create("output.txt")
writer := bufio.NewWriter(file)
writer.WriteString("Hello\n")
writer.WriteString("World\n")
// 必須刷新緩衝區
writer.Flush()
file.Close()使用
bufio.Writer時,必須在結束前呼叫Flush()確保所有資料都被寫入。否則緩衝區中的資料可能會遺失。
Scanner 分詞器#
// 預設按行分割
scanner := bufio.NewScanner(strings.NewReader("word1 word2 word3"))
// 改為按單詞分割
scanner.Split(bufio.ScanWords)
for scanner.Scan() {
fmt.Println(scanner.Text()) // word1, word2, word3
}
// 內建的分割函式
// bufio.ScanLines - 按行(預設)
// bufio.ScanWords - 按單詞
// bufio.ScanRunes - 按 rune
// bufio.ScanBytes - 按位元組自訂分割函式
// 以逗號分割
splitComma := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
if atEOF && len(data) == 0 {
return 0, nil, nil
}
if i := bytes.IndexByte(data, ','); i >= 0 {
return i + 1, data[0:i], nil
}
if atEOF {
return len(data), data, nil
}
return 0, nil, nil
}
scanner := bufio.NewScanner(strings.NewReader("a,b,c,d"))
scanner.Split(splitComma)
for scanner.Scan() {
fmt.Println(scanner.Text()) // a, b, c, d
}