go - 希望使用传递给库的相同文件内容,而无需两次打开文件

标签 go io

我正在使用gopkg.in/freeeve/pgn.v1库读取棋类游戏特有的“pgn”格式的文本文件。它在text/scanner的幕后使用NewPGNScanner

不幸的是,它没有简单的方法来取回从pgn文件接收的输入,因此我将所有文件内容分别拉入缓冲区,然后将其转换为字符串 slice ,以便与NewPGNScanner同时使用(我是非常了解潜在的内存问题,但文件很小,每次游戏内容传递时,我都会从 slice 上移开,从而不断减少消耗的内存):

func main() {
    f, err := os.Open("../before_fide_master.pgn")
    if err != nil {
        log.Fatal(err)
    }

    buf := new(bytes.Buffer)
    buf.ReadFrom(f)
    allPgnBlocks := strings.Split(buf.String(),"\n\n")
    var gamePgnBlocks []string

    // f, err = os.Open("../before_fide_master.pgn")

    pgnContent := pgn.NewPGNScanner(f)

    for pgnContent.Next() {
        game, err := pgnContent.Scan()
        if err != nil {
            log.Fatal(err)
        }

        if len(game.Moves) >= 1 {
            gamePgnBlocks, allPgnBlocks = allPgnBlocks[0:2], allPgnBlocks[2:]
        }

        fmt.Printf("%v\n\n", gamePgnBlocks[0])
        fmt.Printf("%v\n\n", gamePgnBlocks[1])
    }
}

注意注释掉的行。没有它,就不会在for pgnContent.Next()上发生迭代;它需要在程序中以我想要的方式进行注释。因此,似乎buf.ReadFrom(f)干扰了库在后台使用的text/scanner

我在Google上搜索时没有找到任何正确的信息。这个被接受的答案https://stackoverflow.com/a/13514395/34806要求使用ioutil.ReadFile,它当然会再次读取文件-实际上,我的方法基于针对同一问题的投票率较低的答案:https://stackoverflow.com/a/43449991/34806

我也已经开始阅读https://golang.org/pkg/bytes/#Buffer上的文档,而无需研究如何精确地实现某种“倒带”而不必第二次调用该文件上的os.Open。我想可能会在那里,并且我认为这将对将来有类似需求的任何人进行有用的问答,谢谢。

最佳答案

在使用buf.ReadFrom(f)从文件中读取字节之后,似乎是最简单的解决方案,如下所示:

// f, err = os.Open("../before_fide_master.pgn")
f.Seek(0, 0)

感谢mkopriva。我在Google上搜索并找到了f.Seek(0, 0)技术:https://gobyexample.com/reading-files

关于go - 希望使用传递给库的相同文件内容,而无需两次打开文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61728420/

相关文章:

go - 为什么我的 go 程序会出现死锁?

math - Go 数学包的结果无效

go - 如何将我的 Go 代码变成一个库?

c - 非阻塞输入 C

c++ - 打开相对于已执行模块的文件

java - 如何使带有 IO 任务循环的 java 程序更快?

go - Gorm非常慢

go - 通过反射创建然后修改 map

python - 一些输入输出问题

c++ - 使用 std::istream::operator>> 处理无符号类型,我如何区分下溢提取失败?