Dans Go, bufio fournit un moyen pratique de lire et d'écrire des données de manière tamponnée. Cependant, lorsqu'il s'agit de messages séparés par des délimiteurs de saut de ligne de retour chariot (CRLF), le comportement par défaut de bufio.ReadLine peut ne pas suffire. Cet article explore une approche alternative pour lire les messages avec des délimiteurs CRLF à l'aide de bufio.
Pour lire des messages avec des délimiteurs CRLF, nous pouvons utiliser bufio.Scanner en conjonction avec un outil personnalisé fonction de numérisation. La méthode SplitFunc nous permet de définir une fonction personnalisée qui détermine les limites de chaque message.
<code class="go">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 }</code>
Dans la fonction d'analyse personnalisée, nous recherchons les délimiteurs CRLF et renvoyons le message en conséquence. La fonction dropCR garantit que tout r final est supprimé du message.
Maintenant, nous pouvons envelopper notre lecteur avec le scanner personnalisé :
<code class="go">scanner := bufio.NewScanner(this.reader) scanner.Split(ScanCRLF)</code>
En appelant Scan, nous pouvons parcourir le messages dans le lecteur :
<code class="go">for scanner.Scan() { fmt.Printf("%s\n", scanner.Text()) }</code>
Une approche alternative consiste à lire un nombre spécifique d'octets comme spécifié dans l'en-tête du message. Cependant, cette méthode est sujette à des incohérences et peut conduire à un comportement inattendu si le nombre d'octets attendu est incorrect ou s'il y a des données supplémentaires dans le tampon du lecteur.
Pour utiliser cette approche, nous pouvons d'abord lire la ligne d'en-tête. pour obtenir le nombre d'octets attendu :
<code class="go">res, err := this.reader.ReadLine('\n')</code>
Ensuite, nous pouvons créer un lecteur limité avec le nombre d'octets attendu :
<code class="go">nr_of_bytes := // read_number_of_butes_somehow(this.reader) limitedReader := io.LimitReader(this.reader, int64(nr_of_bytes))</code>
Enfin, nous pouvons lire le corps du message à partir de le lecteur limité :
<code class="go">buf := make([]byte, nr_of_bytes) limitedReader.Read(buf)</code>
Cependant, cette approche a ses limites et il est généralement recommandé de s'appuyer sur une approche basée sur les messages utilisant des délimiteurs CRLF.
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!