首页 文章

使用Go从文本文件中读取数据

提问于
浏览
1

我有一个文本文件,其中包含我想要阅读的一些文本数据 . 不幸的是我找不到这样做的方法 .

这是一个例子

5 4
1 2 - Yogurt
2 0 X Chicken soup
3 1 X Cheese 
4 3 X Ham 
2
3
4
0

该文件由三部分组成 . 第一部分是 Headers (第一行),第二部分是记录列表,最后一部分是unit64值列表 .

标头只包含两个值,一个是uint64,后跟一个unit16 . 第二个值是记录的数量以及第三部分中的值的数量,因为这些数字是相同的 .

记录是unit64值,后跟一个uint16值,后跟一个只能是X或 - 的字符,后跟一个utf-8编码的字符串,直到行尾 . 已使用fmt.Fprintf()将数据写入文件 .

第三部分包含uint64值 .

我现在花了几个小时试图找出如何从文本文件中读取这些数据,但找不到方法 .

如果str只包含属于该数字的数字,我只能使用strconv.ParseUint(str,0,64)或uint16(strconv.ParseUint(str,0,16)) . 我查看bufio使用Reader但我可以获得最多的线路 . 我应该使用bufio.Scanner,但我无法确定如何从文档中使用它 .

1 回答

  • 4

    Rubber duck debugging效果再次起作用 . 在提出问题后,我发现了自己的答案 . 这是为了防止其他人遇到同样的问题 .

    在下面的例子中,我将简单地打印出读取的数据

    import (
        "bufio"
        "fmt"
        "log"
        "os"
        "strings"
    )
    
    
    func loadFile( fileName string ) {
        // Open file and instantiate a reader
        file, err := os.Open(fileName)
        if err != nil {
            log.Fatal(err)
        }
        reader := bufio.NewReader(file)
    
        var {
            value0 uint64,
            nbrRows uint16
        }
    
        // Read header values
        if _,err := fmt.Fscanf(reader, "%d %d\n", &value0, &nbrRows); err != nil {
            log.Fatal(err)
        }
    
        // Iterate on the rows 
        for i := uint16(0); i < nbrRows; i++ {
            var {
                value1 uint64,
                value2 uint16,
                value3 string,
                value4 string
            }
    
            // Read first three row values
            if _,err := fmt.Fscanf(reader, "%d %d %s\n", &value1, &value2, &value3); err != nil {
                log.Fatal(err)
            }
            // Read remain of line
            if value4,err := reader.ReadString('\n'); err != nil {
                log.Fatal(err)
            }
            value4 = strings.Trim(value4," \n")
    
            // Display the parsed data
            fmt.Printf("%d %d %s '%s'\n", value1, value2, value3, value4)
        }
    
        // Iterate on the rows containing a single integer value
        for i := uint16(0); i < nbrRows; i++ {
            var value5 uint64
    
            // Read the value
            if _,err := fmt.Fscanf(reader, "%d\n", &value5); err != nil {
                log.Fatal(err)
            }
    
            // Display the parsed data
            fmt.Printf("%d\n", value5)
        }
    }
    

    此代码假定value4不以空格或换行符开头和结尾,这是我的情况 . 这是因为Trim()调用将删除它们 .

相关问题