You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Go的encoding/json解码无数组包裹的JSON流?

解决换行分隔JSON对象的流式解码问题

你的问题核心在于:你想用encoding/json的数组流式解析方式,但你的数据根本不是JSON数组(缺少[]包裹),而是多个独立的JSON对象用逗号和换行分隔。Decoder.Token()一开始就期望读到数组的[,自然会抛出“not at beginning of value”错误。

下面给你两种靠谱的解决思路,对应不同的数据格式情况:

情况1:数据是严格的JSON Lines(每行一个JSON对象,无逗号)

如果你的数据是每行一个完整的JSON对象(没有多余的逗号),那处理起来最简单——直接循环调用Decode直到遇到EOF就行,因为json.Decoder会自动跳过换行、空格这类空白字符:

package main
import (
	"encoding/json"
	"fmt"
	"io"
	"log"
	"strings"
)
func main() {
	// 去掉了每个对象后面的逗号,变成标准JSON Lines格式
	const jsonStream = `
{"Name": "Ed", "Text": "Knock knock."}
{"Name": "Sam", "Text": "Who's there?"}
{"Name": "Ed", "Text": "Go fmt."}
{"Name": "Sam", "Text": "Go fmt who?"}
{"Name": "Ed", "Text": "Go fmt yourself!"}
`
	type Message struct {
		Name, Text string
	}
	dec := json.NewDecoder(strings.NewReader(jsonStream))

	// 循环解码每个对象,直到EOF
	for {
		var m Message
		err := dec.Decode(&m)
		if err != nil {
			if err == io.EOF {
				break // 数据处理完毕,退出循环
			}
			log.Fatal(err)
		}
		fmt.Printf("%v: %v\n", m.Name, m.Text)
	}
}

情况2:数据带逗号分隔(像你的示例那样)

如果你的数据每个对象后面都带逗号,那需要额外处理逗号这个分隔符——因为逗号不是合法的JSON值,Decode遇到它会报错。我们可以用Token()方法先读取并跳过逗号,再解码对象:

package main
import (
	"encoding/json"
	"fmt"
	"io"
	"log"
	"strings"
)
func main() {
	const jsonStream = `
{"Name": "Ed", "Text": "Knock knock."},
{"Name": "Sam", "Text": "Who's there?"},
{"Name": "Ed", "Text": "Go fmt."},
{"Name": "Sam", "Text": "Go fmt who?"},
{"Name": "Ed", "Text": "Go fmt yourself!"}
`
	type Message struct {
		Name, Text string
	}
	dec := json.NewDecoder(strings.NewReader(jsonStream))

	for {
		// 先读取一个token,判断是对象开头还是逗号
		t, err := dec.Token()
		if err != nil {
			if err == io.EOF {
				break
			}
			log.Fatal(err)
		}

		// 如果是对象的{,退回去让Decode完整解析整个对象
		if delim, ok := t.(json.Delim); ok && delim == '{' {
			dec.UnreadToken()
			var m Message
			if err := dec.Decode(&m); err != nil {
				log.Fatal(err)
			}
			fmt.Printf("%v: %v\n", m.Name, m.Text)
		}
		// 如果是逗号,直接跳过,继续下一轮循环
	}
}

这个思路的核心是:不再把数据当成数组来解析,而是逐个处理每个独立的JSON对象,同时跳过用来分隔对象的逗号。

内容的提问来源于stack exchange,提问作者Jay Doh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:07:54