Go語言有三種逐行讀取文件的方法,依次是
ReadString
func (b *Reader) ReadString(delim byte) (string, error)
ReadString從輸入中讀取數據,直到分隔符出現,返回包括分割符在內的字符串。如果ReadString
在找到一個分割符之前就遇到了錯誤,它會返回已讀取的數據和錯誤本身。ReadString返回的
err!=nil,當且僅當它返回的數據不以分割符結尾。Scanner更加易於使用。
使用
str, err := bufio.ReadString('\n')
即可獲得文件中的某一行。
Scanner
type Scanner struct {}
Scanner提供了簡單的讀取數據的接口。連續地調用Scan方法將會跨到文件中的一個個特定符號,
並跳過特定符號之間的字符。這些符號由類型爲SplitFunc的分割函數定義。默認的分割函數是
將輸入按行切割成一塊塊,每一塊結果不包括行結束符。分割函數定義在這個包的內部。用戶可
以自定義分割函數。
該結構提供的方法
func NewScanner(r io.Reader) *Scanner
func (s *Scanner) Buffer(buf []byte, max int)
func (s *Scanner) Bytes() []byte
func (s *Scanner) Err() error
func (s *Scanner) Scan() bool
func (s *Scanner) Split(split SplitFunc)
func (s *Scanner) Text() string
使用
for {
if !buf.Scan() {
break
}
line := buf.Text()
}
即可獲取文件各行。
示例代碼
package main
import (
"fmt"
"os"
"bufio"
"strings"
)
type Person struct {
fname, lname string
}
func main() {
fmt.Println("Please enter the file name.")
var filename string
fmt.Scan(&filename)
f, e := os.Open(filename)
if e != nil {
fmt.Println("File error.")
} else {
var personList []Person
buf := bufio.NewScanner(f)
for {
if !buf.Scan() {
break
}
line := buf.Text()
line = strings.TrimSpace(line)
strSlice := strings.Split(line, " ")
var tmp Person
tmp.fname = strSlice[0]
tmp.lname = strSlice[1]
personList = append(personList, tmp)
}
for _, elt := range(personList) {
fmt.Printf("%s %s\n", elt.fname, elt.lname)
}
}
}
文件names.txt中有
asdlf asdfasdf
asdf asdf
as nknxcv
uio klh
wer ghm
輸入和輸出如下
$ go run read.go
Please enter the file name.
names.txt
asdlf asdfasdf
asdf asdf
as nknxcv
uio klh
wer ghm
ReadLine
func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error)
ReadLine是底層的行讀取原語,不建議使用。