php小编苹果将为大家介绍一种精确读取指定行数(而不是一个字节)的文本的惯用语Go。在处理文本文件时,我们经常需要读取特定行数的内容,而不是逐个字节读取。使用Go语言的bufio包,我们可以轻松实现这个目标。接下来,我们将详细介绍如何使用这个惯用语来实现精确读取指定行数的文本的功能。让我们一起来探索吧!
我有一个来自报告生成器的 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)
以上是惯用语 Go 精确读取 N 行(而不是一个字节)的文本?的详细内容。更多信息请关注PHP中文网其他相关文章!