csv Go语言可以精确地读取N行(而不是一个字节)的文本吗?

nhhxz33t  于 5个月前  发布在  Go
关注(0)|答案(1)|浏览(46)

我有一个来自报告生成器的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的真正开始。
所以我想出了一个办法,就是一个字节一个字节地阅读,直到我数出六个换行符(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()
...


这也行,但是,有没有更地道的围棋方法呢?

ebdffaop

ebdffaop1#

你不需要避免使用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)

字符串
Full Example

相关问题