Maison > développement back-end > Golang > le corps du texte

Comment implémenter un générateur de type \'tail -f\' dans Go : une approche idiomatique avec io.Reader ?

Susan Sarandon
Libérer: 2024-10-29 23:26:29
original
979 Les gens l'ont consulté

How to Implement a

"tail -f"-Like Generator in Go : une approche idiomatique avec io.Reader

Dans le domaine de la programmation, la nécessité de suivre l’évolution du contenu d’un dossier se pose souvent. Python offre une fonction pratique adaptée à cette tâche, semblable au « tail -f » d'UNIX. Cependant, la mise en œuvre d'une fonctionnalité similaire dans Go nécessite une approche différente en raison des nuances de langage.

Dans Go, le code fourni dans la question utilise une goroutine pour surveiller le fichier et générer de nouvelles lignes dès qu'elles deviennent disponibles. Bien que fonctionnel, il peut soulever des inquiétudes quant à l'utilisation des ressources et aux pratiques de programmation idiomatiques Go.

Une solution alternative consiste à créer un wrapper autour d'un io.Reader qui présente un comportement de type « queue ». Cette approche offre un certain nombre d'avantages :

  • Synchronisation simplifiée : L'existence d'un type "tailReader" élimine le besoin de mécanismes de synchronisation complexes entre la goroutine et le code appelant.
  • API Cleaner : En étendant l'interface io.Reader, le "tailReader" s'intègre de manière transparente au code Go existant et aux bibliothèques qui attendent un io.Reader.
  • Consommation de ressources réduite : Sans avoir besoin d'une goroutine dédiée à la surveillance du fichier, l'approche "tailReader" entraîne moins de surcharge et réduit l'utilisation du processeur.

L'implémentation de "tailReader" elle-même est simple :

<code class="go">type tailReader struct {
    io.ReadCloser
}

func (t tailReader) Read(b []byte) (int, error) {
    for {
        n, err := t.ReadCloser.Read(b)
        if n > 0 {
            return n, nil
        } else if err != io.EOF {
            return n, err
        }
        time.Sleep(10 * time.Millisecond)
    }
}</code>
Copier après la connexion

Une fonction d'assistance facultative peut être utilisée pour instancier le "tailReader":

<code class="go">func newTailReader(fileName string) (tailReader, error) {
    f, err := os.Open(fileName)
    if err != nil {
        return tailReader{}, err
    }

    if _, err := f.Seek(0, 2); err != nil {
        return tailReader{}, err
    }
    return tailReader{f}, nil
}</code>
Copier après la connexion

Pour utiliser le "tailReader", enroulez-le simplement autour d'un bufio.Scanner ou autre mécanisme d'E/S basé sur le lecteur :

<code class="go">t, err := newTailReader("somefile")
if err != nil {
    log.Fatal(err)
}
defer t.Close()
scanner := bufio.NewScanner(t)
for scanner.Scan() {
    fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
    fmt.Fprintln(os.Stderr, "reading:", err)
}</code>
Copier après la connexion

En résumé, l'approche "tailReader" exploite les atouts de l'interface du lecteur de Go pour fournir une solution idiomatique et efficace pour suivre le contenu d'un fichier. Il offre simplicité, efficacité des ressources et intégration transparente avec le code Go existant.

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!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal