我有一个来自报告生成器的 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
不要将 传递给os.File
,继续使用可能包含已从文件中读取的数据。csv.NewReader
bufio.NewReader
bufio.Reader
一旦有了
bufio.Reader
,您就可以使用所有方法来读取流的各个部分,而无需担心逐字节读取。完整示例