Go语言读取文本文件的三种方式:逐行、单词与字符
在处理日志分析或配置解析时,按需读取文件内容是常见需求。本文将介绍Go语言中基于标准库的三种文本读取策略:逐行、单词和字符级操作,通过具体代码展示如何实现。
逐行读取文本文件
逐行读取是最常用的文件处理方式,适合处理日志文件或结构化文本。实现核心在于使用 bufio 包的缓冲读写功能,配合 ReadString 方法按换行符分割内容。
第1步:准备环境与依赖
需要导入 bufio、flag、fmt、io 和 os 等标准库。其中 bufio 用于高效读写,flag 用于接收命令行传入的文件路径。
第2步:编写逐行读取逻辑
创建文件读取器并循环读取,直到遇到 EOF(文件结束)标记。以下是完整的 byLine.go 代码实现:
package main
import (
"bufio"
"flag"
"fmt"
"io"
"os"
)
func lineByLine(file string) error {
var err error
f, err := os.Open(file)
if err != nil {
return err
}
defer f.Close()
r := bufio.NewReader(f)
for {
line, err := r.ReadString('\n')
if err == io.EOF {
break
} else if err != nil {
fmt.Printf("error reading file %s", err)
break
}
fmt.Print(line)
}
return nil
}
func main() {
flag.Parse()
if len(flag.Args()) == 0 {
fmt.Printf("usage: byLine <file1> [<file2> ...]\n")
return
}
for _, file := range flag.Args() {
err := lineByLine(file)
if err != nil {
fmt.Println(err)
}
}
}
代码说明:
- bufio.NewReader() 生成带缓冲的读取器。
- r.ReadString('\n') 持续读取直到遇见换行符。
- 当 err == io.EOF 时表示文件读取完毕,正常退出循环;若发生其他错误则打印提示并中断。
第3步:运行与验证
创建一个测试文件 test.txt,包含以下内容并保留换行:
这是第一行
我是第二行
在终端执行以下命令:
$ go run byLine.go test.txt
预期输出结果与原文件一致。可使用 cat test.txt 对比校验数据完整性。
逐个单词读取文本文件
当需要分词处理数据(如自然语言处理的预处理阶段)时,可以使用 scanner.Split 方法按空白符分割内容。此方法更适用于英文或以空格分隔的语言。
第1步:使用 Scanner 扫描单词
与逐行读取类似,但需实例化 bufio.Scanner 并设置分割模式为 bufio.ScanWords。将每个单词追加到切片后遍历打印。
以下为 byWord.go 的核心逻辑:
package main
import (
"bufio"
"flag"
"fmt"
"os"
)
func wordByWord(file string) error {
var err error
f, err := os.Open(file)
if err != nil {
return err
}
defer f.Close()
scanner := bufio.NewScanner(f)
scanner.Split(bufio.ScanWords)
var words []string
for scanner.Scan() {
words = append(words, scanner.Text())
}
for _, word := range words {
fmt.Println(word)
}
return nil
}
func main() {
flag.Parse()
if len(flag.Args()) == 0 {
fmt.Printf("usage: byWord <file1> [file2> ...]\n")
return
}
for _, file := range flag.Args() {
err := wordByWord(file)
if err != nil {
fmt.Println(err)
}
}
}
关键点:
- scanner.Split(bufio.ScanWords) 定义了以空白符作为分隔符的扫描规则。
- 所有单词被存入 words 切片后再统一打印,便于后续处理。
第2步:运行测试
测试文件 test.txt 内容如下:
Hello World
1 2 3
执行命令:
$ go run byWord.go test.txt
输出结果为:
Hello
World
1
2
3
逐个字符读取文本文件
个别场景(如自定义编辑器或极细粒度的数据处理)需要逐字符遍历。虽然性能开销较大且用途相对狭窄,但该模式展示了 Go 对 Unicode 码点的处理机制。
第1步:实现逐字符解析
在逐行读取的基础上,对每一行字符串进行范围遍历(range),将其转换为单字符字符串输出。以下是 byCharacter.go 的实现:
package main
import (
"bufio"
"flag"
"fmt"
"io"
"os"
)
func charByChar(file string) error {
var err error
f, err := os.Open(file)
if err != nil {
return err
}
defer f.Close()
r := bufio.NewReader(f)
for {
line, err := r.ReadString('\n')
if err == io.EOF {
break
} else if err != nil {
fmt.Printf("error reading file %s", err)
return err
}
for _, x := range line {
fmt.Println(string(x))
}
}
return nil
}
func main() {
flag.Parse()
if len(flag.Args()) == 0 {
fmt.Printf("usage: byWord <file1> [file2> ...]\n")
return
}
for _, file := range flag.Args() {
err := charByChar(file)
if err != nil {
fmt.Println(err)
}
}
}
注意:
- 此处依然利用换行符界定大段内容,但在内部对每一行进行了字符级别的展开。
- string(x) 将 rune 类型的码点转换为可读字符串。
第2步:验证结果
继续使用之前的 test.txt,执行:
$ go run byCharacter.go test.txt
控制台将逐行打印每个字母及其空格的占位符,符合预期结构。
总结
本文演示了在 Go 中如何利用 bufio 包灵活应对不同粒度的文本读取需求。
- 逐行读取适合常规日志解析。
- 单词分割适合基础的分词统计。
- 字符遍历则针对特殊格式化处理。
对于更复杂的 CSV 解析或二进制文件处理,建议后续引入专门的第三方库或进一步封装逻辑。以上就是Go语言读取文本文件的三种方式总结的详细内容,更多关于Go语言文本操作技巧的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













