我有这样的代码
scanner := bufio.NewScanner(reader)
scanner.Split(splitJSON)
for scanner.Scan() {
bb := scanner.Bytes()
}
我想一次只从 Scanner 获取一个有效的 JSON 对象。在某些情况下,在 Scanner 中可能是这样表示结构的字节
{
"some_object": "name",
"some_fileds": {}
}
{
"some_object":
}
我只需要这个的第一部分
{
"some_object": "name",
"some_fileds": {}
}
对于另一个,我应该等待 JSON 对象的结束。
我有一个这样的函数,但它太糟糕了而且不起作用。
func splitJSON(
bb []byte, atEOF bool,
) (advance int, token []byte, err error) {
print(string(bb))
if len(bb) < 10 {
return 0, nil, nil
}
var nested, from, to int
var end bool
for i, b := range bb {
if string(b) == "{" {
if end {
to = i
break
}
if nested == 0 {
from = i
}
nested++
}
if string(b) == "}" {
nested--
if nested == 0 {
to = i
end = true
}
}
}
if atEOF {
return len(bb), bb, nil
}
return len(bb[from:to]), bb[from:to], nil
}
更新 由这个splitFunc决定
func splitJSON(data []byte, atEOF bool) (advance int, token []byte, err error) {
if atEOF && len(data) == 0 {
return 0, nil, nil
}
reader := bytes.NewReader(data)
dec := json.NewDecoder(reader)
var raw json.RawMessage
if err := dec.Decode(&raw); err != nil {
return 0, nil, nil
}
return len(raw) + 1, raw, nil
}
最佳答案
使用json.Decoder
为了这。每个Decoder.Decode()
调用将从您的案例中的输入 JSON 对象解码下一个 JSON 编码值。
如果您不想解码只需要 JSON 数据(字节 slice )的 JSON 对象,请使用 json.RawMessage
解编成。
例如:
func main() {
reader := strings.NewReader(src)
dec := json.NewDecoder(reader)
for {
var raw json.RawMessage
if err := dec.Decode(&raw); err != nil {
if err == io.EOF {
break
}
fmt.Printf("Error:", err)
return
}
fmt.Println("Next:", string(raw))
}
}
const src = `{
"some_object": "name",
"some_fileds": {}
}
{
"some_object": "foo"
}`
这将输出(在 Go Playground 上尝试):
Next: {
"some_object": "name",
"some_fileds": {}
}
Next: {
"some_object": "foo"
}
关于json - 如何为扫描 json 对象的 bufio.Scaner 编写自定义 splitFunc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73786151/