首頁  >  文章  >  後端開發  >  慣用語 Go 精確讀取 N 行(而非一個位元組)的文字?

慣用語 Go 精確讀取 N 行(而非一個位元組)的文字?

WBOY
WBOY轉載
2024-02-09 08:40:09980瀏覽

惯用语 Go 精确读取 N 行(而不是一个字节)的文本?

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中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除