在Go语言开发中,文本文件统计是常见的基础需求,比如统计日志文件的行数、统计文档的单词数量、统计文件的字符总数等。实现这类功能核心是先掌握Golang的文件读取方式,再结合字符串处理逻辑完成统计。

Golang文件读取基础
Go语言标准库的os包和bufio包提供了完善的文件操作能力,读取文本文件常用两种方式:一种是使用ioutil(Go 1.16后为os包的ReadFile)一次性读取全部内容,适合小文件;另一种是使用bufio.Scanner逐行读取,适合大文件避免内存占用过高。
一次性读取文件
使用os.ReadFile可以直接读取整个文件内容,返回字节切片,后续转换为字符串处理即可,代码示例如下:
package main
import (
"fmt"
"os"
)
func main() {
// 读取目标文本文件,替换为实际文件路径
content, err := os.ReadFile("./test.txt")
if err != nil {
fmt.Printf("读取文件失败: %vn", err)
return
}
// 转换为字符串方便后续处理
text := string(content)
fmt.Printf("文件内容长度: %d 字符n", len(text))
}
逐行读取文件
如果文件体积较大,一次性读取会占用过多内存,此时可以使用bufio.Scanner逐行扫描文件,每次处理一行内容,代码示例如下:
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
// 打开文件
file, err := os.Open("./test.txt")
if err != nil {
fmt.Printf("打开文件失败: %vn", err)
return
}
defer file.Close()
// 创建Scanner逐行扫描
scanner := bufio.NewScanner(file)
lineCount := 0
for scanner.Scan() {
lineCount++
// 这里可以处理每一行的内容
lineText := scanner.Text()
fmt.Printf("第%d行内容: %sn", lineCount, lineText)
}
if err := scanner.Err(); err != nil {
fmt.Printf("扫描文件出错: %vn", err)
}
fmt.Printf("文件总行数: %dn", lineCount)
}
文本文件统计功能实现
结合文件读取能力,我们可以实现常见的文本统计功能,包括行数统计、单词数统计、字符数统计,下面给出完整的实现示例。
统计规则说明
- 行数:以换行符
n为分隔,统计文件的总行数,空行也计入行数 - 单词数:以空白字符(空格、制表符、换行符等)为分隔,统计连续非空白字符组成的单词数量
- 字符数:统计文件所有字符的数量,包含空白字符和换行符
完整统计示例代码
以下代码实现了上述三种统计功能,同时兼容小文件和大文件场景,使用逐行读取的方式处理:
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
// 统计结果结构体
type FileStat struct {
LineCount int // 行数
WordCount int // 单词数
CharCount int // 字符数
}
func CountTextFile(filePath string) (*FileStat, error) {
file, err := os.Open(filePath)
if err != nil {
return nil, err
}
defer file.Close()
stat := &FileStat{}
scanner := bufio.NewScanner(file)
for scanner.Scan() {
// 统计行数,每行扫描到就加1
stat.LineCount++
line := scanner.Text()
// 统计当前行的字符数,包含行内的所有字符
stat.CharCount += len(line)
// 统计单词数,按空白字符分割
words := strings.Fields(line)
stat.WordCount += len(words)
}
// 处理扫描过程中的错误
if err := scanner.Err(); err != nil {
return nil, err
}
// 补充换行符的字符数,每行有一个换行符,除了最后一行可能没有
// 这里简化统计,直接加上行数(假设每行有一个换行符)
stat.CharCount += stat.LineCount
return stat, nil
}
func main() {
// 替换为实际要统计的文件路径
filePath := "./test.txt"
stat, err := CountTextFile(filePath)
if err != nil {
fmt.Printf("统计文件失败: %vn", err)
return
}
fmt.Printf("文件统计结果:n")
fmt.Printf("总行数: %dn", stat.LineCount)
fmt.Printf("总单词数: %dn", stat.WordCount)
fmt.Printf("总字符数: %dn", stat.CharCount)
}
注意事项
在实际使用中需要注意几个问题:首先是文件路径的正确性,相对路径是相对于程序运行目录的,如果找不到文件可以先打印绝对路径确认;其次是编码问题,上述代码默认处理UTF-8编码的文本文件,如果是其他编码需要先转码再统计;最后是超大文件的处理,逐行读取的方式已经避免一次性加载全部内容,适合GB级别的文件统计。
通过上述方法,就可以快速用Golang实现文本文件的各类统计功能,开发者可以根据实际需求调整统计规则,比如过滤空行、统计特定字符出现次数等,核心思路都是先正确读取文件内容,再按照规则处理字符串即可。