Go 標準庫中的?
bufio
?包提供了帶緩沖的讀寫功能,可以顯著提高文件和數據處理效率。而?bufio.Scanner
?則是讀取文本文件中每一行的利器,常用于日志、配置等文本處理場景。
一、為什么使用?bufio
?
直接對文件進行?os.File.Read()
?或?os.File.Write()
?操作是無緩沖的,每次調用都會進行系統調用,效率較低。
bufio
?在內部使用內存緩沖區,減少與操作系統的交互,性能提升明顯。
二、bufio.Reader
:帶緩沖的讀取
示例:讀取文件內容并逐行輸出
file,?err?:=?os.Open("sample.txt")
if?err?!=?nil?{log.Fatal(err)
}
defer?file.Close()reader?:=?bufio.NewReader(file)for?{line,?err?:=?reader.ReadString('\n')if?err?==?io.EOF?{break}if?err?!=?nil?{log.Fatal(err)}fmt.Print(line)
}
方法說明:
- ??
ReadString(delim byte)
:讀到指定分隔符為止(如?\n
)。 - ??
ReadBytes(delim byte)
:與?ReadString
?類似,但返回字節切片。 - ??
ReadLine()
:低級函數,建議用?Scanner
?替代。 - ??
Peek(n int)
:讀取但不消費前?n
?個字節。
三、bufio.Writer
:帶緩沖的寫入
file,?_?:=?os.Create("output.txt")
defer?file.Close()writer?:=?bufio.NewWriter(file)
writer.WriteString("Hello,?buffered?write!\n")
writer.Flush()?//?必須顯式刷新緩沖區
注意:?使用?
bufio.Writer
?寫入數據后,需要調用?Flush()
?將數據寫入底層文件或網絡連接,否則可能數據不會立即寫入。
四、bufio.Scanner
:按行或自定義分隔符掃描輸入
1. 按行讀取文本文件
file,?_?:=?os.Open("sample.txt")
defer?file.Close()scanner?:=?bufio.NewScanner(file)
for?scanner.Scan()?{fmt.Println(scanner.Text())
}if?err?:=?scanner.Err();?err?!=?nil?{log.Fatal(err)
}
2. 自定義分隔符(如按空格、逗號、段落分隔)
scanner?:=?bufio.NewScanner(strings.NewReader("go?is?simple.?go?is?fast."))//?自定義按單詞分割
scanner.Split(bufio.ScanWords)for?scanner.Scan()?{fmt.Println(scanner.Text())
}
常見分割器:
- ??
bufio.ScanLines
(默認) - ??
bufio.ScanWords
- ??
bufio.ScanBytes
五、Scanner 與大文件的關系
- ??
Scanner
?默認緩沖區大小為 64K,如需處理超大行文本,可以通過?scanner.Buffer()
?提高上限:
scanner.Buffer(make([]byte,?1024),?10*1024*1024)?//?提升最大支持到10MB
六、小結
類型 | 功能 | 適合場景 |
bufio.Reader | 提供高效逐行或按字節讀取 | 網絡流、日志、長行文本等 |
bufio.Writer | 高效寫入并可緩沖 | 寫文件、網絡輸出 |
bufio.Scanner | 方便讀取行、單詞等小粒度內容 | 配置文件、日志文件、終端輸入 |
七、建議實踐練習
- 1. 寫一個程序,讀取大文件并統計每一行的字符數。
- 2. 模擬 tail -f,持續從文件末尾讀取新增內容。
- 3. 實現一個按單詞頻率排序的詞頻統計器。