Maison  >  Article  >  développement back-end  >  Comment lire des données multilignes délimitées par CRLF dans Go ?

Comment lire des données multilignes délimitées par CRLF dans Go ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-10-26 20:09:29101parcourir

How to Read Multi-Line Data Delimited by CRLF in Go?

Lecture de données multilignes délimitées par CRLF dans Go

Lorsque vous travaillez avec des protocoles qui transmettent des messages multilignes, il devient nécessaire de gérer efficacement les données séparées par des lignes. Dans ce cas, la question se pose de savoir comment lire les données d'un tampon jusqu'à ce que la séquence de caractères délimiteurs CRLF se produise.

Utiliser un bufio.SplitFunc personnalisé

Pour relever ce défi, une solution consiste à définissez un bufio.SplitFunc personnalisé qui reconnaît la séquence CRLF comme terminaison de ligne. Voici un exemple d'implémentation :

<code class="go">import (
    "bufio"
    "bytes"
)

func ScanCRLF(data []byte, atEOF bool) (advance int, token []byte, err error) {
    if atEOF && len(data) == 0 {
        return 0, nil, nil
    }
    if i := bytes.Index(data, []byte{'\r', '\n'}); i >= 0 {
        // We have a full newline-terminated line.
        return i + 2, dropCR(data[0:i]), nil
    }
    // If we're at EOF, we have a final, non-terminated line. Return it.
    if atEOF {
        return len(data), dropCR(data), nil
    }
    // Request more data.
    return 0, nil, nil
}

func dropCR(data []byte) []byte {
    if len(data) > 0 && data[len(data)-1] == '\r' {
        return data[0 : len(data)-1]
    }
    return data
}</code>

Cette fonction ScanCRLF peut être utilisée pour diviser des données en fonction des délimiteurs CRLF.

Lecteur d'emballage avec scanner

Avec la fonction ScanCRLF personnalisée, vous pouvez envelopper le io.Reader d'origine avec un bufio.Scanner pour lire les données plus efficacement :

<code class="go">scanner := bufio.NewScanner(r)
scanner.Split(ScanCRLF)

// Read chunks of data until EOF
for scanner.Scan() {
    fmt.Printf("%s\n", scanner.Text())
}

if err := scanner.Err(); err != nil {
    fmt.Printf("Invalid input: %s", err)
}</code>

Gestion du compteur d'octets inattendus

La suggestion alternative de lire un nombre spécifique d'octets en fonction de un compteur d'octets peut ne pas être fiable en raison d'erreurs potentielles dans le compteur lui-même. Des valeurs inattendues ou incorrectes dans le compteur peuvent entraîner une corruption des données ou des messages tronqués.

Par conséquent, l'approche préférée consiste à utiliser un mécanisme de type machine à états pour analyser le protocole, y compris la commande et la longueur de corps attendue, et de vérifier la longueur réelle du corps par rapport à cette valeur attendue. Cela garantit l’intégrité et la robustesse des données.

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:
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