标准流的操作
从标准输入中查找重复的行
// 从标准输入中查找重复的行
func main() {
counts := make(map[string]int, 0)
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
counts[scanner.Text()]++
}
for key, value := range counts {
if value > 1 {
fmt.Println("输出======",key)
}
}
}
命令行输入和输出(需要等一定超时时间才能输出,可以按control+D发送中断信号可直接输出并结束)
123
123
3
1
1
输出====== 123
输出====== 1
文件操作
下面文件名scanner.go
func main() {
cmdArgs := os.Args[1:]
files := make([]*os.File, 0)
for _, path := range cmdArgs {
// 打开文件,以读写方式打开,如果没有则创建
file, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0777)
if err != nil {
fmt.Println("打开文件失败:", path,"失败原因:", err)
return
}
// 收集文件指针
files = append(files, file)
}
// 文件名-总行数映射,文件名-去重行数映射,文件名-去重行映射
allLineCountMap, distinctLineCountMap, distinctLineMap := FileLineCount(files)
// 遍历打印结果
for _, file := range files {
fmt.Println("文件名:", file.Name(), " 行数:", allLineCountMap[file.Name()], " 去重行数:",distinctLineCountMap[file.Name()], "去重行:")
for _, line :=range distinctLineMap[file.Name()] {
fmt.Println(line)
}
}
}
// 文件统计,总行数,去重行数,去重行
func FileLineCount(files []*os.File) (allLineCountMap map[string]int, distinctLineCountMap map[string]int, distinctLineMap map[string][]string) {
// 固定缓冲区大小,用来读文件
bytes := make([]byte, 512, 512)
// 文件结尾会返回io.EOF固定错误,用来判断文件遍历完成
var err error
// 文件名对应字节数组映射
fileNameToByteMap := make(map[string][]byte, 0)
// 遍历文件数组
for _, file := range files {
n := 0
err = nil
fileByte := make([]byte, 0, 1024)
for err != io.EOF {
// n是读取到了多少个字节,err是本次读取的错误信息
n, err = file.Read(bytes)
if n > 0 {
fileByte = append(fileByte, bytes[0:n]...)
// 清空bytes数组
for i := 0; i < n; i++ {
bytes[i] = 0
}
} else {
fileNameToByteMap[file.Name()] = fileByte
}
if err == io.EOF {
// 读文件结束,跳出内层循环
break
}
}
}
allLineCountMap = make(map[string]int, 0)
distinctLineCountMap = make(map[string]int, 0)
distinctLineMap = make(map[string][]string, 0)
// 读文件字节数组,统计行数
for fileName, fileBytes := range fileNameToByteMap {
// 字节数组按照\n分割
lines := strings.Split(string(fileBytes), "\n")
// 统计总行数
allLineCountMap[fileName] = len(lines)
// 统计去重行数
distinctMap := make(map[string]int, 0)
for _, line := range lines {
distinctMap[line]++
}
distinctLines := make([]string, 0, len(distinctLineMap))
for key := range distinctMap {
distinctLines = append(distinctLines, key)
}
distinctLineCountMap[fileName] = len(distinctMap)
distinctLineMap[fileName] = distinctLines
}
return
}
使用
- 创建测试文件text1.txt
流程1
流程1
a
a
- 创建测试文件text2.txt
123
123
123
123
123
123
123
123
123
- 执行go build scanner.go,生成scanner可执行文件
- 执行./scanner ./text1.txt ./text2.txt(目录需要改成自己的)
- 执行结果
文件名: ./text1.txt 行数: 5 去重行数: 3 去重行:
流程1
a
文件名: ./text2.txt 行数: 9 去重行数: 1 去重行:
123