登录
首页 >  Golang >  Go问答

如何以行为单位而不是以字节为单位精确读取 N 行文本?

来源:stackoverflow

时间:2024-02-06 08:09:21 209浏览 收藏

在IT行业这个发展更新速度很快的行业,只有不停止的学习,才不会被行业所淘汰。如果你是Golang学习者,那么本文《如何以行为单位而不是以字节为单位精确读取 N 行文本?》就很适合你!本篇内容主要包括##content_title##,希望对大家的知识积累有所帮助,助力实战开发!

问题内容

我有一个来自报告生成器的 CSV,它添加了一些非 CSV 前导码,例如:

Time Off Requests

My Org
Street Address
City, State  ZIP

Col1,Col2,Col3
r1c1,r1c2,r1c3
r2c1,r2c2,r2c3

在将文件的 io.Reader 传递给 csv.NewReader 并尝试 ReadAll() 之前,我需要丢弃这 6 行,因此我需要确保我不会读取第 6 行之后的任何一个字节。

我最初想到 bufio.Scanner 并在循环中调用 Scan() 6 次,但后来通过实验意识到 bufio 中的“buf”意味着我无法控制缓冲读取的结束位置,并且它可能会读取超过真正开始的位置CSV。

所以我想出了一个办法,就是逐字节读取,直到数到 6 个换行符 (10):

f, _ := os.Open(csvPath)

// Read just past report-generated 6-line preamble
b := make([]byte, 1)
for i := 0; i < 6; {
    f.Read(b)
    if b[0] == 10 {
        i++
    }
}

r := csv.NewReader(f)
records, err = r.ReadAll()
...

这有效。但是,有更惯用的 Go 方式吗?


正确答案


您不需要避免使用 bufio,事实上您应该尽可能选择使用缓冲 IO。您不能做的是通过 bufio.Reader 访问它之后使用原始阅读器,即,在使用 bufio.NewReader 后,不要将 os.File 传递给 csv.NewReader,继续使用 bufio.Reader 可能包含已从文件中读取的数据。

一旦有了 bufio.Reader,您就可以使用所有方法来读取流的各个部分,而无需担心逐字节读取。

buf := bufio.NewReader(f)
// the preambled is defined as 6 lines
for i := 0; i < 6; i++ {
    line, err := buf.ReadBytes('\n')
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("line: %q\n", line)
}
r := csv.NewReader(buf)
records, err := r.ReadAll()
if err != nil {
    log.Fatal(err)
}
fmt.Printf("records: %q\n", records)

完整示例

理论要掌握,实操不能落!以上关于《如何以行为单位而不是以字节为单位精确读取 N 行文本?》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>