bufio.scanner 读不到换行符后的数据,因其默认以\n为分隔符且自动丢弃该符;末尾无换行时最后一次扫描可能被忽略;超长行触发“token too long”错误,需用buffer()扩容;保留换行符应改用reader的readbytes或readstring。
bufio.Scanner 为什么读不到换行符后的数据?
因为 bufio.Scanner 默认以 \n 为分隔符,且会自动丢弃分隔符本身;若输入末尾无换行(比如用户 Ctrl+D 直接结束),最后一次扫描可能被忽略,或 Scan() 返回 false 却没报错。
- 用
scanner.Bytes()或scanner.Text()前,必须先调用scanner.Scan()并检查返回值 - 若需保留换行符,改用
bufio.Reader的ReadBytes('\n')或ReadString('\n') - 默认缓冲区大小为 64KB,超长行会触发
"bufio.Scanner: token too long"错误,可通过scanner.Buffer(nil, max)扩容
bufio.Reader.Read() 和 ReadSlice(‘\n’) 行为差异
Read() 是底层字节读取,不识别分隔符,容易读多或读少;ReadSlice() 会一直读直到遇到指定字节(含该字节),但返回的是底层缓冲区的切片——如果后续继续调用其他读方法,该切片可能被覆盖。
- 安全做法:用
ReadString('\n')(返回新字符串)或对ReadSlice()结果立即做append([]byte{}, ...)拷贝 -
ReadSlice()在未找到分隔符时返回ErrBufferFull,不是 EOF —— 它只表示当前缓冲区满了,不代表输入结束 - 若输入源是管道或网络连接,
ReadSlice()可能阻塞等待分隔符;而Read()只要底层有数据就返回,更适合流式解析协议头
bufio.Writer.Flush() 什么时候必须显式调用?
只要写入的数据还没刷到底层 io.Writer(比如文件、网络连接),就存在丢失风险。常见于程序退出前、长连接中发送完整消息后、或写入量小于缓冲区容量时。