Maison  >  Article  >  développement back-end  >  Idiom Go pour lire exactement N lignes (au lieu d'un octet) de texte ?

Idiom Go pour lire exactement N lignes (au lieu d'un octet) de texte ?

WBOY
WBOYavant
2024-02-09 08:40:09928parcourir

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

L'éditeur php Apple vous présentera un idiome Go qui lit avec précision un nombre spécifié de lignes (plutôt qu'un octet) de texte. Lorsque nous travaillons avec des fichiers texte, nous devons souvent lire un nombre spécifique de lignes, plutôt que de lire octet par octet. En utilisant le package bufio du langage Go, nous pouvons facilement atteindre cet objectif. Ensuite, nous détaillerons comment utiliser cet idiome pour réaliser la fonction de lecture précise d’un nombre spécifié de lignes de texte. Explorons ensemble !

Contenu de la question

J'ai un CSV provenant d'un générateur de rapports qui ajoute des préambules non CSV comme :

Time Off Requests

My Org
Street Address
City, State  ZIP

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

Je dois supprimer ces 6 lignes avant de transmettre le io.Reader du fichier à csv.NewReader et d'essayer ReadAll() , je dois donc m'assurer de ne lire aucun octet après la ligne 6.

Au départ, j'ai pensé à bufio.Scanner et j'ai appelé Scan() 6 fois en boucle, mais j'ai réalisé plus tard grâce à l'expérimentation que le "buf" dans bufio signifie que je n'ai aucun contrôle sur l'endroit où se termine la lecture en mémoire tampon, et qu'elle peut lire plus que le réelle Position de départ CSV.

J'ai donc trouvé une solution, qui consiste à lire octet par octet jusqu'à compter 6 nouvelles lignes (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()
...

Cela fonctionne. Mais existe-t-il une méthode Go plus idiomatique ?

Solution de contournement

Vous n'avez pas besoin d'éviter d'utiliser bufio,事实上您应该尽可能选择使用缓冲 IO。您不能做的是通过 bufio.Reader 访问它之后使用原始阅读器,即,在使用 bufio.NewReader 后,不要将 os.File 传递给 csv.NewReader,继续使用 bufio.Reader qui peut contenir des données qui ont été lues à partir d'un fichier.

Une fois que vous avez bufio.Reader, vous pouvez utiliser toutes les méthodes pour lire des parties du flux sans vous soucier de la lecture octet par octet.

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)

Exemple complet

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer