Dalam Go, bufio menyediakan cara yang mudah untuk membaca dan menulis data secara penimbal. Walau bagaimanapun, apabila berurusan dengan mesej yang dipisahkan oleh pembatas suapan talian pulangan (CRLF), tingkah laku lalai bufio.ReadLine mungkin tidak mencukupi. Artikel ini meneroka pendekatan alternatif untuk membaca mesej dengan pembatas CRLF menggunakan bufio.
Untuk membaca mesej dengan pembatas CRLF, kami boleh menggunakan bufio.Scanner bersama-sama dengan tersuai fungsi pengimbasan. Kaedah SplitFunc membolehkan kami mentakrifkan fungsi tersuai yang menentukan sempadan setiap mesej.
<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>
Dalam fungsi pengimbasan tersuai, kami mencari pembatas CRLF dan mengembalikan mesej dengan sewajarnya. Fungsi dropCR memastikan bahawa sebarang r yang mengekori dialih keluar daripada mesej.
Kini, kami boleh membalut pembaca kami dengan pengimbas tersuai:
<code class="go">scanner := bufio.NewScanner(this.reader) scanner.Split(ScanCRLF)</code>
Dengan memanggil Scan, kami boleh mengulangi melalui mesej dalam pembaca:
<code class="go">for scanner.Scan() { fmt.Printf("%s\n", scanner.Text()) }</code>
Pendekatan alternatif ialah membaca bilangan bait tertentu seperti yang dinyatakan dalam pengepala mesej. Walau bagaimanapun, kaedah ini terdedah kepada ketidakkonsistenan dan boleh menyebabkan tingkah laku yang tidak dijangka jika kiraan bait yang dijangkakan tidak betul atau jika terdapat data tambahan dalam penimbal pembaca.
Untuk menggunakan pendekatan ini, kita boleh membaca baris pengepala terlebih dahulu. untuk mendapatkan bilangan bait yang dijangkakan:
<code class="go">res, err := this.reader.ReadLine('\n')</code>
Kemudian, kita boleh mencipta pembaca terhad dengan bilangan bait yang dijangkakan:
<code class="go">nr_of_bytes := // read_number_of_butes_somehow(this.reader) limitedReader := io.LimitReader(this.reader, int64(nr_of_bytes))</code>
Akhir sekali, kita boleh membaca kandungan mesej daripada pembaca terhad:
<code class="go">buf := make([]byte, nr_of_bytes) limitedReader.Read(buf)</code>
Walau bagaimanapun, pendekatan ini mempunyai hadnya dan secara amnya disyorkan untuk bergantung pada pendekatan berasaskan mesej menggunakan pembatas CRLF.
Atas ialah kandungan terperinci Cara Membaca Mesej CRLF-Delimited dalam Go with Bufi. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!