Golang实现两个文本文件的逐行对比
Golang实现两个文本文件的逐行对比 我想知道如何在 Go 语言中实现两个文本(.txt)文件的逐行比较。
例如,file1 的内容: Hello world! Hello Bob! Lorem ipsum
file2 的内容: Hello world! Not matched line Lorem ipsum Not matched line
如你所见,第 1 行和第 3 行是相同的。
结果应该类似于: file1 与 file2 比较:3 行中有 2 行相同。 file2 与 file1 比较:4 行中有 2 行相同。
2 回复
你好 Valentyn!
虽然这不能完全解决你的问题,但下面的代码展示了如何打开一个文件并逐行读取。我不太确定如何同时扫描两个文件,但你可以尝试将每个文件读入一个字符串切片中,每个索引代表一行。
然后,处理这两个 []string 并比较它们的每个索引就会更容易。这种方法效率不高,因为你需要分配两个切片然后遍历它们,但如果它满足你的使用场景,也是可行的。
file, err := os.Open("file1.txt")
if err != nil {
panic(err)
}
scanner := bufio.NewScanner(file)
var file1Lines []string
for scanner.Scan() {
currentLineText := scanner.Text()
file1Lines = append(file1Lines, currentLineText)
}
更多关于Golang实现两个文本文件的逐行对比的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
// 读取文件1
file1, err := os.Open("file1.txt")
if err != nil {
fmt.Printf("无法打开file1.txt: %v\n", err)
return
}
defer file1.Close()
// 读取文件2
file2, err := os.Open("file2.txt")
if err != nil {
fmt.Printf("无法打开file2.txt: %v\n", err)
return
}
defer file2.Close()
// 创建扫描器
scanner1 := bufio.NewScanner(file1)
scanner2 := bufio.NewScanner(file2)
// 逐行比较
lineNum := 1
matchedLines := 0
totalLines1 := 0
totalLines2 := 0
// 同时读取两个文件
for scanner1.Scan() || scanner2.Scan() {
line1 := ""
line2 := ""
if scanner1.Scan() {
line1 = scanner1.Text()
totalLines1++
}
if scanner2.Scan() {
line2 = scanner2.Text()
totalLines2++
}
// 比较当前行
if line1 == line2 {
matchedLines++
fmt.Printf("第 %d 行匹配: %s\n", lineNum, line1)
} else {
fmt.Printf("第 %d 行不匹配:\n", lineNum)
if line1 != "" {
fmt.Printf(" file1: %s\n", line1)
}
if line2 != "" {
fmt.Printf(" file2: %s\n", line2)
}
}
lineNum++
}
// 检查扫描错误
if err := scanner1.Err(); err != nil {
fmt.Printf("读取file1.txt时出错: %v\n", err)
}
if err := scanner2.Err(); err != nil {
fmt.Printf("读取file2.txt时出错: %v\n", err)
}
// 输出统计结果
fmt.Printf("\n统计结果:\n")
fmt.Printf("file1 与 file2 比较:%d 行中有 %d 行相同。\n", totalLines1, matchedLines)
fmt.Printf("file2 与 file1 比较:%d 行中有 %d 行相同。\n", totalLines2, matchedLines)
}
如果需要更详细的比较,比如找出哪些行不同,可以使用以下增强版本:
package main
import (
"bufio"
"fmt"
"os"
)
func compareFiles(file1Path, file2Path string) error {
// 读取文件1的所有行
lines1, err := readAllLines(file1Path)
if err != nil {
return fmt.Errorf("读取文件1失败: %v", err)
}
// 读取文件2的所有行
lines2, err := readAllLines(file2Path)
if err != nil {
return fmt.Errorf("读取文件2失败: %v", err)
}
// 找出匹配的行
matchedCount := 0
maxLines := max(len(lines1), len(lines2))
fmt.Println("逐行比较结果:")
for i := 0; i < maxLines; i++ {
line1 := ""
line2 := ""
if i < len(lines1) {
line1 = lines1[i]
}
if i < len(lines2) {
line2 = lines2[i]
}
if line1 == line2 && line1 != "" {
matchedCount++
fmt.Printf("✓ 第 %d 行: %s\n", i+1, line1)
} else {
fmt.Printf("✗ 第 %d 行:\n", i+1)
if line1 != "" {
fmt.Printf(" file1: %s\n", line1)
}
if line2 != "" {
fmt.Printf(" file2: %s\n", line2)
}
}
}
// 输出统计信息
fmt.Printf("\n文件统计:\n")
fmt.Printf("file1 总行数: %d\n", len(lines1))
fmt.Printf("file2 总行数: %d\n", len(lines2))
fmt.Printf("匹配行数: %d\n", matchedCount)
fmt.Printf("file1 与 file2 比较:%d 行中有 %d 行相同。\n", len(lines1), matchedCount)
fmt.Printf("file2 与 file1 比较:%d 行中有 %d 行相同。\n", len(lines2), matchedCount)
return nil
}
func readAllLines(filePath string) ([]string, error) {
file, err := os.Open(filePath)
if err != nil {
return nil, err
}
defer file.Close()
var lines []string
scanner := bufio.NewScanner(file)
for scanner.Scan() {
lines = append(lines, scanner.Text())
}
if err := scanner.Err(); err != nil {
return nil, err
}
return lines, nil
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
func main() {
if err := compareFiles("file1.txt", "file2.txt"); err != nil {
fmt.Printf("比较文件时出错: %v\n", err)
}
}
这两个示例都实现了逐行比较文本文件的功能。第一个版本使用流式处理,适合大文件;第二个版本将文件内容读入内存,提供更详细的比较信息。

