为了账号安全,请及时绑定邮箱和手机立即绑定

如何在Go中逐个字符地读取文件

如何在Go中逐个字符地读取文件

Go
波斯汪 2021-10-25 20:32:52
我有一些要解析的大型 json 文件,并且我想避免将所有数据一次加载到内存中。我想要一个函数/循环,可以一次返回一个字符。我发现这个例子用于迭代字符串中的单词,而bufio 包中的 ScanRunes函数看起来可以一次返回一个字符。我也有ReadRune来自 bufio的功能主要工作,但这感觉是一种非常沉重的方法。编辑我比较了 3 种方法。所有人都使用循环从 bufio.Reader 或 bufio.Scanner 中提取内容。使用.ReadRuneon a循环读取符文bufio.Reader。检查调用中的错误.ReadRune。bufio.Scanner在调用.Split(bufio.ScanRunes)扫描器后从 a 读取字节。调用.Scan并.Bytes在每次迭代,检查.Scan调用错误。与#2 相同,但bufio.Scanner使用.Text.从 a而不是字节读取文本。string([]runes)我没有加入一片符文,而是加入了一片字符串strings.Join([]strings, "")以形成最终的文本块。在 23 MB json 文件上各运行 10 次的时间为:0.65 s2.40 s0.97 s所以看起来ReadRune毕竟还不错。它还导致更小、更简洁的调用,因为每个符文都是在 1 个操作 ( .ReadRune) 而不是 2 个 (.Scan和.Bytes) 中获取的。
查看完整描述

3 回答

?
MMTTMM

TA贡献1869条经验 获得超4个赞

只需在循环中一个一个地读取每个符文...参见示例


package main


import (

    "bufio"

    "fmt"

    "io"

    "log"

    "strings"

)


var text = `

The quick brown fox jumps over the lazy dog #1.

Быстрая коричневая лиса перепрыгнула через ленивую собаку.

`


func main() {

    r := bufio.NewReader(strings.NewReader(text))

    for {

        if c, sz, err := r.ReadRune(); err != nil {

            if err == io.EOF {

                break

            } else {

                log.Fatal(err)

            }

        } else {

            fmt.Printf("%q [%d]\n", string(c), sz)

        }

    }

}


查看完整回答
反对 回复 2021-10-25
?
千巷猫影

TA贡献1829条经验 获得超7个赞

此代码从输入读取符文。不需要强制转换,它类似于迭代器:


package main


import (

    "bufio"

    "fmt"

    "strings"

)


func main() {

    in := `{"sample":"json string"}`


    s := bufio.NewScanner(strings.NewReader(in))

    s.Split(bufio.ScanRunes)


    for s.Scan() {

        fmt.Println(s.Text())

    }

}


查看完整回答
反对 回复 2021-10-25
  • 3 回答
  • 0 关注
  • 268 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信