【问题标题】:golang reading a large number using bufio.NewScannergolang 使用 bufio.NewScanner 读取大量数据
【发布时间】:2021-04-15 15:17:10
【问题描述】:

我试图获取输入(许多带有空格的数字)并将其转换为切片。 数字数量高达 300,000

我遇到了一个错误,我用谷歌搜索了它。并且缓冲区大小存在一些问题。 所以我写了如下代码。

func ChangeToInt(input string) []int {
    var nums []int
    for _, word := range strings.Fields(input) {
        num, _ := strconv.Atoi(word)
        nums = append(nums, num)
    }
    return nums
}

scanner := bufio.NewScanner(os.Stdin)

maxCapacity := 4*300000
buf := make([]byte, maxCapacity)
scanner.Buffer(buf, maxCapacity)

scanner.Scan()
input := scanner.Text()
nums := ChangeToInt(input)  

但仍然无法正常工作。有什么问题?

【问题讨论】:

  • what's the problem? 好问题。
  • “不工作”是什么意思?你会得到什么错误,如果有的话?

标签: go


【解决方案1】:

您正在使用bufio.Scanner 来读取您的输入。默认情况下bufio.Scanner 读取行,并使用内部缓冲区来存储行。默认情况下,该行的最大长度可能为bufio.MaxScanTokenSize,即 64 KB。如果你的行比这长,你会得到一个错误。

可以使用Scanner.Buffer() 方法更改/增加内部缓冲区大小,但如果您输入的是空格分隔的数字列表,我建议更改Scanner 的拆分功能。

如前所述,默认情况下,扫描仪按分割输入。而是将其更改为按 words 分割输入。 bufio 包有一个“准备好”的拆分功能:bufio.Scanwords。像这样使用它:

scanner := bufio.NewScanner(os.Stdin)
scanner.Split(bufio.ScanWords)

现在scanner.Text() 将返回单词(在您的情况下为数字)而不是完整的行,因此默认的 64 KB 限制现在适用于单词,而不是行。您的数字应小于 64 KB。

同时调用scanner.Err()检查扫描是否成功。

【讨论】:

    【解决方案2】:

    您可以使用bufio.NewReader 及其ReadString('\n') 方法。它适用于大量输入数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-16
      • 2016-12-16
      • 1970-01-01
      • 2013-10-19
      • 1970-01-01
      相关资源
      最近更新 更多