go语言文件操作

标准流的操作
从标准输入中查找重复的行

// 从标准输入中查找重复的行
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
}

使用

  1. 创建测试文件text1.txt
流程1
流程1

a
a
  1. 创建测试文件text2.txt
123
123
123
123
123
123
123
123
123
  1. 执行go build scanner.go,生成scanner可执行文件
  2. 执行./scanner ./text1.txt ./text2.txt(目录需要改成自己的)
  3. 执行结果
文件名: ./text1.txt  行数: 5  去重行数: 3 去重行:
流程1

a
文件名: ./text2.txt  行数: 9  去重行数: 1 去重行:
123
  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值