使用傳送多行訊息的協定時,有必要有效地處理行分隔資料。在這種情況下,出現的問題是如何從緩衝區讀取數據,直到出現分隔符號字元序列 CRLF。
要解決這個挑戰,一種解決方案是定義一個自訂 bufio.SplitFunc ,將 CRLF 序列識別為行終止符。以下是範例實作:
<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>
此 ScanCRLF 函數可用於根據 CRLF 分隔符號分割資料。
使用自訂ScanCRLF 函數,你可以用bufio.Scanner 包裝原始io.Reader 更有效地讀取資料:
<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>
基於讀取特定位元組數的替代建議由於計數器本身存在潛在錯誤,位元組計數器可能不可靠。計數器中意外或不正確的值可能會導致資料損壞或訊息被截斷。
因此,首選方法是使用類似狀態機的機制來解析協議,包括命令和預期的正文長度,並根據該預期值驗證實際體長。這確保了數據的完整性和穩健性。
以上是Go中如何讀取以CRLF分隔的多行資料?的詳細內容。更多資訊請關注PHP中文網其他相關文章!