前言
文件 I/O,特別是對文件的讀寫是編程語言中重要的功能。通常,我們需要逐行讀取文件。
GO 提供了 bufio 軟件包,實現了有緩沖的 I/O。它包裝一個 io.Reader 或 io.Writer 接口對象,創建另一個也實現了該接口,且同時還提供了緩沖和一些文本 I/O 的幫助函數的對象。
在讀取文件之前,我們首先需要使用 os.Open() 函數將其打開,該函數返回指向文件的指針類型。代碼段中顯示的 D:\\go_work\\test.txt 文件需要已經存在在系統中(將路徑放置到文件所在的位置)。
bufio.NewScanner(file) 函數創建並返回一個從 r 讀取數據的 Scanner 類型,該類型中的函數支持讀取文件,其中默認的分割函數是 ScanLines。
要逐行讀取文件,我們需要使用兩種在新的 Scanner 的方法 Scan,它會獲取當前位置的 token(該 token 可以通過 Bytes 或 Text 方法獲得,在本例中為新行),並讓 Scanner 的掃描位置移動到下一個 token,和 Text(或 Byte)讀取調用 Scan 時生成的最新符記。
如果在讀取文件時遇到任何錯誤,可以通過在新的 Scanner 上調用 Err() 方法來處理這些錯誤,該方法將返回 Scanner 遇到的第一個非文件結尾錯誤;除非是 io.EOF,此時 Err 會返回 nil。
Go 逐行讀取文件的完整代碼
package main
import (
"bufio"
"fmt"
"log"
"os"
)
func main() {
// open the file
file, err := os.Open("D:\\go_work\\test.txt")
// handle errors while opening
if err != nil {
log.Fatalf("Error when opening file: %s", err)
}
defer file.Close()
fileScanner := bufio.NewScanner(file)
// read line by line
for fileScanner.Scan() {
fmt.Println(fileScanner.Text())
}
// handle first encountered error while reading
if err := fileScanner.Err(); err != nil {
log.Fatalf("Error while reading file: %s", err)
}
}
配置 Scanner 行為
Scanner 類型具有 Split 函數,該函數接受 SplitFunc 函數來確定 Scanner 如何拆分給定的字節片。默認的 SplitFunc 是 ScanLines,它將返回文本的每一行,並刪除行尾標記。
例如,我們可以使用單詞進行拆分,如下面的代碼片段所示:
scanner.Split(bufio.ScanWords) //configure how the scanner behaves
