Go语言读取文本文件的三种方式:逐行、单词与字符

咖啡半糖
咖啡半糖
发布时间:2026-10-15 | 5人浏览过
原创

在处理日志分析或配置解析时,按需读取文件内容是常见需求。本文将介绍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语言文本操作技巧的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表