首页 > 解决方案 > 在 golang 中,json.Unmarshal() 在操场/复制粘贴的 JSON 中有效,但在实际代码中无效

问题描述

我正在用 Golang 编写一个程序,该程序与修改版的赤脚地图匹配库接口,该库通过 netcat 以 json 格式返回结果。

我在我的实际代码json.Unmarshal中只会解析对结构的 nil 值的响应。但是,如果将 json 打印到控制台(请参见下面的代码片段)并将粘贴复制到 goplayground 中,它的行为将符合预期。

我想知道这是否是我从控制台复制粘贴时绕过的编码问题。

如何让我的代码处理从赤脚接收到的字符串与从控制台复制粘贴时相同的字符串?

这是相关的代码片段(结构与 goplayground 相同)

body := io_func(conn, cmd)
    var obvs []Json_out
    json.Unmarshal([]byte(body), &obvs)
    fmt.Println(body)
    fmt.Println(obvs)

如果相关(响应是两行,io_func()第一行是消息,第二行是 json 字符串)

func io_func(conn net.Conn, cmd string) string {
    fmt.Fprintf(conn, cmd+"\n")
    r := bufio.NewReader(conn)
    header, _ := r.ReadString('\n')
    if header == "SUCCESS\n" {
        resp, _ := r.ReadString('\n')
    return resp
    } else {
        return ""
    }

}

标签: jsongounmarshalling

解决方案


io_func 函数创建并丢弃一个 bufio.Reader 和读取器可能缓冲的数据。如果应用程序多次调用 io_func,则应用程序可能正在丢弃从网络读取的数据。通过在函数外部创建单个 bufio.Reader 并将该单个阅读器传递给 io_func 的每个调用来修复。

始终检查和处理错误。这些函数中的任何一个返回的错误都可能为您指明正确的修复方向。

func io_func(r *bufio.Reader, conn net.Conn, cmd string) (string, error) {
    fmt.Fprintf(conn, cmd+"\n")
    header, err := r.ReadString('\n')
    if err != nil {
        return "", err
    }
    if header == "SUCCESS\n" {
        return r.ReadString('\n')
    }
    return "", nil
}


...

r := bufio.NewReader(conn)

body, err := io_func(r, conn, cmd)
if err != nil {
    // handle error
}
var obvs []Json_out
err = json.Unmarshal([]byte(body), &obvs)
if err != nil {
    // handle error
}
fmt.Println(body)
fmt.Println(obvs)

// read next 
body, err = io_func(r, conn, cmd)
if err != nil {
    // handle error
}

应用程序使用换行符来终止 JSON 正文,但换行符是 JSON 中的有效空格。如果对等方在 JSON 中包含换行符,则应用程序将读取部分消息。


推荐阅读