ReadString()会在换行后丢弃字节吗?

时间:2017-09-19 21:11:27

标签: go

我试图通过以下方式从网络连接中读取:

func getIn(conn net.Conn){
    for{
        in, err := bufio.NewReader(conn).ReadString('\n')
        if err!=nil{
            fmt.Printf(err.Error())
        }
        fmt.Printf("[%s]", in)
    }
}

发送到该连接的输入流具有以下模式:

  

message1 \ n message2 \ n message3 \ n message4 \ n message5 \ n

等...

我注意到我的功能会跳过消息,输出例如:

  

message1 \ nmessage2 \ nmessage4 \ n message5 \ n

这使我认为每次遇到换行符时,bufio ReadString方法都会丢弃传入缓冲区。假设缓冲区包含:

  

MESSAGE1 \ nmess

在阅读的那一刻。然后, message1 被读取,剩余的部分 mess 将被丢弃。这也不完全有意义,因为接下来的输入应该是 age2 ,但实际上它是 message3

我使用了一个不同的函数net.Conn.Read(),它确实没有跳过输入的任何部分,但需要更多的字符串解析。如何让ReadString()函数适合我?

1 个答案:

答案 0 :(得分:2)

ReadString()不会丢弃数据,它仍在<{1}}对象中缓冲,即:

bufio.Reader

请注意,尽管所有数据都来自conn := bytes.NewBufferString("message1\n message2\n message3\n ") reader := bufio.NewReader(conn) in, _ := reader.ReadString('\n') // "message1\n" fmt.Println(strconv.Quote(in)) in, _ = reader.ReadString('\n') // "message2\n" fmt.Println(strconv.Quote(in)) fmt.Println(strconv.Quote(conn.String())) // "" 缓冲区,但仍可通过后续conn调用访问。但是,您在每次迭代时丢弃读取器对象,并且所有数据都将丢失。

您应该在循环外创建缓冲读取器,这样您仍然可以在第二个循环中使用读者:

reader.ReadString()