“顶级值”后面有无效字符’\x00’。

huangapple go评论88阅读模式
英文:

"invalid character '\x00' after top-level value"

问题

在使用for循环进行JSON反序列化时,我遇到了这个错误。第一次循环时,反序列化正常,但在下一次迭代时,我遇到了这个错误。

我对Go语言还不太熟悉,这个错误信息并不清楚。请问有人可以解释一下这个错误发生的情况以及我应该如何避免它吗?

英文:

I am getting this error while unmarshalling json in a for loop.
The first time through the loop is unmarshalling fine but on the next iteration I am getting this error.

I am new to golang and this error message is not clear. Can someone please explain in what cases this error occurs and how I am supposed to avoid it.

答案1

得分: 25

查看encoding/json/scanner.go的源代码

// stateEndTop是在完成顶级值之后的状态,
// 例如在读取`{}`或`[1,2,3]`之后。
// 现在只能看到空格字符。
func stateEndTop(s *scanner, c int) int {
	if c != ' ' && c != '\t' && c != '\r' && c != '\n' {
		// 在下一次调用时报告非空格字节。
		s.error(c, "after top-level value")
	}
	return scanEnd
}

因此,请检查你的JSON字符串是如何结束的。

例如,在这个线程中,为了说明一个潜在的问题:

> ReadFromUDP可以返回任意大小的数据包,从1到2000字节,你需要使用实际读取的字节数重新切片你的缓冲区。

json.Unmarshal(buf[:n], &msg)

这个线程中也是一样:

request := make([]byte, 1024)
read_len, err := conn.Read(request)
request_right := request[:read_len]
j := new(Json)
err := j.UnmarshalJSON(request) // 不起作用

> 如果read_len < len(request),那么request末尾将包含额外的"\x00",
这就是为什么UnmarshalJSON(request)不起作用的原因。

英文:

Looking at the source code of encoding/json/scanner.go

// stateEndTop is the state after finishing the top-level value,
// such as after reading `{}` or `[1,2,3]`.
// Only space characters should be seen now.
func stateEndTop(s *scanner, c int) int {
	if c != &#39; &#39; &amp;&amp; c != &#39;\t&#39; &amp;&amp; c != &#39;\r&#39; &amp;&amp; c != &#39;\n&#39; {
		// Complain about non-space byte on next call.
		s.error(c, &quot;after top-level value&quot;)
	}
	return scanEnd
}

So check how your JSON string ends.

For example, in this thread, to illustrate a potential issue:

> ReadFromUDP can return a packet of any size, from 1 to 2000 bytes, you need to reslice your buffer using the number of bytes actually read.

json.Unmarshal(buf[:n], &amp;msg)

Same in this thread:

request := make([]byte, 1024)
read_len, err := conn.Read(request)
request_right := request[:read_len]
j := new(Json)
err := j.UnmarshalJSON(request) // not working

> if read_len &lt; len(request) then request will contain extra "\x00" at the end
and that's why UnmarshalJSON(request) won't work.

答案2

得分: 15

谢谢你回答我的问题。

这个错误是由于之前的错误的 JSON 导致的,在此之前还有一点更多的故事,

我有一个类型为 json.RawMessage 的字段 detail,我有一个 SELECT 查询,我试图从表中读取 JSON 并将其扫描到 detail 并将其附加到结构体中。

在循环结束后,当我查看 detail 的 JSON 时,它多次出现相同的记录,有时有括号,有时没有括号。经过深思熟虑后,我发现将 detail 强制转换为字节有所帮助。

例如:不要只是使用 rows.Scan(&detail),尝试这样做:
rows.Scan((*[]byte)(&detail)) 解决了上述问题

英文:

Thank you for answering my question.

This error came due to incorrect json before that there is little more story to this,

I have a field detail of type json.RawMessage I have SELECT query where I am trying to read json from the table and scan to detail and appending it to the struct.

After for loop ends when I look at detail JSON it got same record multiple times with and without end braces. After giving it so much thinking I figured casting detail with byte helped.

Eg: instead of just rows.Scan(&detail) try this:
rows.Scan((*[]byte)(&detail)) solved the above problem

huangapple
  • 本文由 发表于 2014年8月8日 00:32:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/25187718.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定