08.5.1 逐行读取文本文件
逐行读取文本文件是最常用的方式。这也是我们首先介绍它的原因。byLine.go程序分为三部分,将帮助你理解这个技巧。
byLine.go第一部分代码如下:
1
package main
2
3
import (
4
"bufio"
5
"flag"
6
"fmt"
7
"io"
8
"os"
9
)
Copied!
引入bufio包表示我们将使用缓冲区输入。
1
func lineByLine(file string) error {
2
var err error
3
4
f, err := os.Open(file)
5
if err != nil {
6
return err
7
}
8
defer f.Close()
9
10
r := bufio.NewReader(f)
11
for {
12
line, err := r.ReadString('\n')
13
if err == io.EOF {
14
break
15
} else if err != nil {
16
fmt.Printf("error reading file %s", err)
17
break
18
}
19
fmt.Printf(line)
20
}
21
return nil
22
}
Copied!
所有的实现都在lineByLine()函数中。在确保可以打开指定的文件名进行读取之后,你调用bufio.NewReader()创建一个新的读实例,然后你可以调用bufio.ReadString()逐行读取文件。行分隔符通过bufio.ReadString()参数指定,它指示bufio.ReadString()一直读取,直到碰到行分隔符为止。当参数是换行符时,不断调用bufio.ReadString()会逐行读取输入文件!注意,使用fmt.Print()而不是fmt.Println()输出读取行,来显示每个输入行中都包含换行符。
byLine.go第三部分代码如下:
1
func main() {
2
flag.Parse()
3
if len(flag.Args()) == 0 {
4
fmt.Printf("usage: byLine <file1> [<file2> ...]\n")
5
return
6
}
7
8
for _, file := range flag.Args() {
9
err := lineByLine(file)
10
if err != nil {
11
fmt.Println(err)
12
}
13
}
14
}
Copied!
执行byLine.go,并使用wc(1)处理输出会产生如下的输出内容:
1
$ go run byLine.go /tmp/swtag.log /tmp/adobegc.log | wc
2
4761 88521 568402
Copied!
如下的命令会校验前述输出的精确性:
1
$ wc /tmp/swtag.log /tmp/adobegc.log
2
131 693 8440 /tmp/swtag.log
3
4630 87828 559962 /tmp/adobegc.log
4
4761 88521 568402 total
Copied!
Last modified 2yr ago
Copy link