我有一堆JSON文件,每个文件包含大量复杂数据。 JSON文件类似于:
ids.json
{
"ids": [1,2,3]
}
names.json:
{
"names": ["Tyrion","Jaime","Cersei"]
}
,依此类推。 (实际上,数组元素是具有十个字段的复杂结构对象)
我想提取 just 标签,该标签指定其包含的数组类型。目前,我正在使用encoding/json
将整个文件解组为map[string]interface{}
并遍历地图,但这是一项昂贵的操作。
是否有一种更快的方式来做到这一点,最好不要拆散整个数据?
答案 0 :(得分:1)
您可以在打开花括号后立即使阅读器偏移,然后使用json.Decoder
仅解码来自阅读器的第一个令牌
类似的事情
sr := strings.NewReader(`{
"ids": [1,2,3]
}`)
for {
b, err := sr.ReadByte()
if err != nil {
fmt.Println(err)
return
}
if b == '{' {
break
}
}
d := json.NewDecoder(sr)
var key string
err := d.Decode(&key)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(key)
https://play.golang.org/p/xJJEqj0tFk9
另外,您可以将io.Reader
中获得的open
用bufio.Reader
包装,以避免多次单字节写操作
此解决方案假定内容是有效的JSON对象。并不是说您还是可以避免这种情况。
答案 1 :(得分:1)
我有个玩法,Decoder.Token()
一次读取一个令牌(请参阅此example,第87行),并且可以提取数组标签:
const jsonStream = `{
"ids": [1,2,3]
}`
dec := json.NewDecoder(strings.NewReader(jsonStream))
t, err := dec.Token()
if err != nil {
log.Fatal(err)
}
fmt.Printf("First token: %v\n", t)
t, err = dec.Token()
if err != nil {
log.Fatal(err)
}
fmt.Printf("Second token (array label): %v\n", t)