In Go bietet bufio eine bequeme Möglichkeit, Daten zu lesen und zu schreiben gepuffert. Beim Umgang mit Nachrichten, die durch CRLF-Trennzeichen (Carriage Return Line Feed) getrennt sind, reicht das Standardverhalten von bufio.ReadLine jedoch möglicherweise nicht aus. In diesem Artikel wird ein alternativer Ansatz zum Lesen von Nachrichten mit CRLF-Trennzeichen mithilfe von bufio untersucht.
Um Nachrichten mit CRLF-Trennzeichen zu lesen, können wir bufio.Scanner in Verbindung mit einem benutzerdefinierten verwenden Scanfunktion. Mit der SplitFunc-Methode können wir eine benutzerdefinierte Funktion definieren, die die Grenzen jeder Nachricht bestimmt.
<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>
In der benutzerdefinierten Scanfunktion suchen wir nach CRLF-Trennzeichen und geben die Nachricht entsprechend zurück. Die dropCR-Funktion stellt sicher, dass alle nachgestellten r aus der Nachricht entfernt werden.
Jetzt können wir unseren Reader mit dem benutzerdefinierten Scanner umschließen:
<code class="go">scanner := bufio.NewScanner(this.reader) scanner.Split(ScanCRLF)</code>
Durch den Aufruf von Scan können wir den durchlaufen Nachrichten im Reader:
<code class="go">for scanner.Scan() { fmt.Printf("%s\n", scanner.Text()) }</code>
Ein alternativer Ansatz besteht darin, eine bestimmte Anzahl von Bytes zu lesen, wie im Nachrichtenheader angegeben. Allerdings ist diese Methode anfällig für Inkonsistenzen und kann zu unerwartetem Verhalten führen, wenn die erwartete Byteanzahl falsch ist oder zusätzliche Daten im Lesepuffer vorhanden sind.
Um diesen Ansatz zu verwenden, können wir zuerst die Headerzeile lesen um die erwartete Anzahl an Bytes zu erhalten:
<code class="go">res, err := this.reader.ReadLine('\n')</code>
Dann können wir einen begrenzten Reader mit der erwarteten Anzahl an Bytes erstellen:
<code class="go">nr_of_bytes := // read_number_of_butes_somehow(this.reader) limitedReader := io.LimitReader(this.reader, int64(nr_of_bytes))</code>
Schließlich können wir den Nachrichtentext daraus lesen der eingeschränkte Leser:
<code class="go">buf := make([]byte, nr_of_bytes) limitedReader.Read(buf)</code>
Dieser Ansatz hat jedoch seine Grenzen und es wird allgemein empfohlen, sich auf einen nachrichtenbasierten Ansatz mit CRLF-Trennzeichen zu verlassen.
Das obige ist der detaillierte Inhalt vonSo lesen Sie CRLF-getrennte Nachrichten in Go mit Bufi. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!