zoukankan      html  css  js  c++  java
  • Golang: 读取文件并统计内容

    上次我们从命令行接收用户输入,并统计了每次输入内容出现的次数,今天对程序加以改造,使其能够读取文件内容,并统计每行文本出现的次数。

    首先,我们把接收输入的逻辑封装成一个函数:

    // scan.go
    
    package main
    
    import (
        "os"
        "fmt"
        "bufio"
    )
    
    func main() {
        counts := make(map[string]int)
    
        fmt.Printf("Please type in something:
    ")
    
        countLines(os.Stdin, counts)
    
        for line, n := range counts {
            fmt.Printf("%d : %s
    ", n, line)
        }
    }
    
    // 统计行数
    func countLines(file *os.File, counts map[string]int) {
        input := bufio.NewScanner(file)
    
        for input.Scan() {
            line := input.Text()
    
            if line == "bye" {
                break
            }
    
            counts[line]++
        }
    }
    

    上面的 coutLines() 函数有两个参数:file *os.File 和 counts map[string]int,第一个参数可以接收标准输入或文件对象,第二个参数接收一个 map 引用。

    然后,我们移除接收命令行输入的逻辑,替换为读取当前目录下的 test.txt 文件:

    // scan.go
    
    package main
    
    import (
        "os"
        "fmt"
        "bufio"
    )
    
    func main() {
        counts := make(map[string]int)
    
        // 打开文件
        file, err := os.Open("test.txt")
    
        // 异常处理
        if err != nil {
            fmt.Fprintf(os.Stderr, "%v
    ", err)
            return
        }
    
        countLines(file, counts)
    
        // 关闭文件
        file.Close()
    
        for line, n := range counts {
            fmt.Printf("%d : %s
    ", n, line)
        }
    }
    
    // 统计行数
    func countLines(file *os.File, counts map[string]int) {
        input := bufio.NewScanner(file)
    
        for input.Scan() {
            counts[input.Text()]++
        }
    }
    

    我们使用 os.Open 打开 test.txt 文件,如果出现异常,则进行异常处理,如果读取成功,则统计内容,最后关闭文件。

    test.txt 文件内容如下:

    hello
    world
    hello
    

    下面是程序的运行结果:

    $ go run scan.go
    # 输出内容
    2 : hello
    1 : world
    

    除上述方式之外,我们还可以使用 io/ioutil 中的方法来读取文件,然后以换行符分割进行统计,实现代码如下:

    // split.go
    
    package main
    
    import (
        "os"
        "fmt"
        "strings"
        "io/ioutil"
    )
    
    func main() {
        counts := make(map[string]int)
    
        // 读取文件
        data, err := ioutil.ReadFile("test.txt")
    
        // 异常处理
        if err != nil {
            fmt.Fprintf(os.Stderr, "%v
    ", err)
            return
        }
    
        // 将数据转换为字符串 然后以换行符分割
        lines := strings.Split(string(data), "
    ")
    
        for _, line := range lines {
            counts[line]++
        }
    
        for line, n := range counts {
            fmt.Printf("%d : %s
    ", n, line)
        }
    }
    
  • 相关阅读:
    函数声明例子
    税收工资分级
    attribute函数
    输出结果有误
    scanf_s()函数与数组,运行环境VS2013
    格式化输出
    功能点介绍和用户场景
    第二次作业合作版
    word count
    第一次作业
  • 原文地址:https://www.cnblogs.com/liuhe688/p/9597741.html
Copyright © 2011-2022 走看看