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

I am using the library gopkg.in/freeeve/pgn.v1 to read text files in a "pgn" format specific to chess games. It uses text/scanner under the hood of its NewPGNScanner.

Unfortunately it provides no easy way to get back the input it takes in from the pgn file, so I am separately pulling in all the file contents into a buffer, which I convert to a string slice, to work with simultaneously with NewPGNScanner (I am well aware of the potential memory issues but the files are small, and I unshift from the slice on every pass over the game contents, thereby continually decreasing the memory consumed):

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])
    }
}

Note the commented out line. Without it, no iteration occurs over for pgnContent.Next(); it needs to be commented in for my program to proceed in the way that I'd like. So it seems that buf.ReadFrom(f) is interfering with the text/scanner being used under the hood by the library.

I have googled without finding anything quite on point. This accepted answer https://stackoverflow.com/a/13514395/34806 calls for using ioutil.ReadFile which of course reads the file yet again -- I actually based my approach on an less up-voted answer for the same question: https://stackoverflow.com/a/43449991/34806

I've also started reading the docs at https://golang.org/pkg/bytes/#Buffer without honing in on how exactly I might achieve some sort of "rewind" without having to call os.Open on the file a second time. I think it might be in there though, and I think this will make a useful Q&A for anybody who has a similar need in the future, thanks.

评论