【问题标题】:Reading data from a text file with Go使用 Go 从文本文件中读取数据
【发布时间】:2013-06-17 16:33:46
【问题描述】:

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

这是一个例子

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

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

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

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

第三部分包含 uint64 值。

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

如果 str 仅包含属于该数字的数字,我只能使用 strconv.ParseUint(str, 0, 64) 或 uint16(strconv.ParseUint(str, 0, 16))。 我查看了 bufio 以使用阅读器,但我最多只能得到几行。 我可能应该使用 bufio.Scanner 但我无法从文档中确定如何使用它。

【问题讨论】:

  • 也许stackoverflow.com/questions/5884154/… 可以提供帮助
  • 我找到了,但没有帮助。我最终使用了 fmt.Scanf(...)。要读取行尾字符串,我必须修剪字符串,因为 ReadString('\n') 返回一个前面有空格,结尾有 \n 的字符串。

标签: go


【解决方案1】:

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() 调用将删除它们。

【讨论】:

  • 我喜欢这种技术,不幸的是我倾向于使用当时最接近的人作为我指定的鸭子。他们通常很困惑,但偶尔会提供令人惊讶的好建议!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-24
  • 1970-01-01
  • 1970-01-01
  • 2022-11-19
  • 2021-06-12
相关资源
最近更新 更多