前言
文件 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