package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
// 读取第一个文件(邮箱列表)到map中,便于快速查找
emailSet := make(map[string]bool)
// 打开第一个文件
file1, err := os.Open("first.txt")
if err != nil {
panic(err)
}
defer file1.Close()
// 逐行读取第一个文件
scanner1 := bufio.NewScanner(file1)
for scanner1.Scan() {
email := strings.TrimSpace(scanner1.Text())
if email != "" {
emailSet[email] = true
}
}
if err := scanner1.Err(); err != nil {
panic(err)
}
// 打开第二个文件
file2, err := os.Open("second.txt")
if err != nil {
panic(err)
}
defer file2.Close()
// 创建第三个输出文件
file3, err := os.Create("third.txt")
if err != nil {
panic(err)
}
defer file3.Close()
writer := bufio.NewWriter(file3)
defer writer.Flush()
// 逐行读取第二个文件
scanner2 := bufio.NewScanner(file2)
for scanner2.Scan() {
line := strings.TrimSpace(scanner2.Text())
if line == "" {
continue
}
// 分割邮箱和哈希值
parts := strings.SplitN(line, ":", 2)
if len(parts) != 2 {
continue
}
email := parts[0]
// 检查邮箱是否存在于第一个文件中
if emailSet[email] {
// 写入到第三个文件
_, err := writer.WriteString(line + "\n")
if err != nil {
panic(err)
}
}
}
if err := scanner2.Err(); err != nil {
panic(err)
}
fmt.Println("处理完成!结果已保存到 third.txt")
}
对于大数据量处理,这里提供一个优化版本,使用更高效的内存管理:
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
// 使用更节省内存的方式处理大文件
emailSet := make(map[string]struct{})
// 处理第一个文件
processFile("first.txt", func(line string) {
email := strings.TrimSpace(line)
if email != "" {
emailSet[email] = struct{}{}
}
})
// 处理第二个文件并输出到第三个文件
file3, err := os.Create("third.txt")
if err != nil {
panic(err)
}
defer file3.Close()
writer := bufio.NewWriter(file3)
defer writer.Flush()
processFile("second.txt", func(line string) {
line = strings.TrimSpace(line)
if line == "" {
return
}
// 查找冒号位置
colonIndex := strings.Index(line, ":")
if colonIndex == -1 {
return
}
email := line[:colonIndex]
// 检查邮箱是否存在
if _, exists := emailSet[email]; exists {
writer.WriteString(line + "\n")
}
})
fmt.Println("处理完成!")
}
func processFile(filename string, processLine func(string)) {
file, err := os.Open(filename)
if err != nil {
panic(err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
buf := make([]byte, 0, 64*1024)
scanner.Buffer(buf, 1024*1024)
for scanner.Scan() {
processLine(scanner.Text())
}
if err := scanner.Err(); err != nil {
panic(err)
}
}
这个解决方案:
- 使用map存储第一个文件的所有邮箱,实现O(1)时间复杂度的查找
- 逐行处理第二个文件,避免一次性加载大文件到内存
- 使用
strings.SplitN或strings.Index分割邮箱和哈希值
- 包含错误处理和资源清理
- 第二个版本针对大数据量进行了优化,使用更大的缓冲区