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是底层的行读取原语,不建议使用。