在 Go 中,bufio 提供了一种便捷的数据读写方式以缓冲的方式。但是,在处理由回车换行符 (CRLF) 分隔符分隔的消息时,bufio.ReadLine 的默认行为可能不够。本文探讨了使用 bufio 读取带有 CRLF 分隔符的消息的替代方法。
要读取带有 CRLF 分隔符的消息,我们可以将 bufio.Scanner 与自定义函数结合使用扫描功能。 SplitFunc 方法允许我们定义一个自定义函数来确定每条消息的边界。
<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>
在自定义扫描函数中,我们搜索 CRLF 分隔符并相应地返回消息。 dropCR 函数确保从消息中删除任何尾随的 r。
现在,我们可以使用自定义扫描仪包装我们的阅读器:
<code class="go">scanner := bufio.NewScanner(this.reader) scanner.Split(ScanCRLF)</code>
通过调用 Scan,我们可以迭代阅读器中的消息:
<code class="go">for scanner.Scan() { fmt.Printf("%s\n", scanner.Text()) }</code>
另一种方法是读取消息标头中指定的特定数量的字节。然而,这种方法很容易出现不一致的情况,如果预期的字节计数不正确或者读取器缓冲区中有其他数据,则可能会导致意外的行为。
要使用这种方法,我们可以首先读取标题行获得预期的字节数:
<code class="go">res, err := this.reader.ReadLine('\n')</code>
然后,我们可以创建一个具有预期字节数的有限阅读器:
<code class="go">nr_of_bytes := // read_number_of_butes_somehow(this.reader) limitedReader := io.LimitReader(this.reader, int64(nr_of_bytes))</code>
最后,我们可以从受限读者:
<code class="go">buf := make([]byte, nr_of_bytes) limitedReader.Read(buf)</code>
但是,这种方法有其局限性,通常建议依赖使用 CRLF 分隔符的基于消息的方法。
以上是如何使用 Bufi 读取 Go 中以 CRLF 分隔的消息的详细内容。更多信息请关注PHP中文网其他相关文章!