从json流读取映射
我需要解析非常长的json文件(超过百万个条目)。我不想把它加载到内存中,然后一块一块地读。有一个关于项目数组的好例子。问题是我要处理地图。当我调用从json流读取映射,json,go,Json,Go,我需要解析非常长的json文件(超过百万个条目)。我不想把它加载到内存中,然后一块一块地读。有一个关于项目数组的好例子。问题是我要处理地图。当我调用Decode时,我得到的不是在值的开头。 我弄不到该换的东西 常数数据=`{ “对象1”:{“名称”:“牛”,“位置”:“厨房”}, “object2”:{“name”:“table”,“location”:“office”} }` 类型ReadObject struct{ 名称字符串`json:“名称”` 位置字符串`json:“位置”` } f
Decode
时,我得到的不是在值的开头。
我弄不到该换的东西
常数数据=`{
“对象1”:{“名称”:“牛”,“位置”:“厨房”},
“object2”:{“name”:“table”,“location”:“office”}
}`
类型ReadObject struct{
名称字符串`json:“名称”`
位置字符串`json:“位置”`
}
func ParseJSON(){
dec:=json.NewDecoder(strings.NewReader(数据))
tkn,err:=dec.Token()
如果错误!=零{
log.Fatalf(“未能读取开始标记:%v”,错误)
}
fmt.Printf(“开始标记:%v\n”,tkn)
对象:=make(映射[字符串]*ReadObject)
十二月更多(){
var nextSymbol字符串
如果错误:=dec.Decode(&nextSymbol);错误!=nil{
log.Fatalf(“未能分析下一个符号:%v”,错误)
}
下一个对象:=&ReadObject{}
如果错误:=dec.Decode(&nextObject);错误!=nil{
log.Fatalf(“未能分析下一个对象”)
}
对象[nextSymbol]=nextObject
}
tkn,err=dec.Token()
如果错误!=零{
log.Fatalf(“未能读取结束标记:%v”,错误)
}
fmt.Printf(“结束标记:%v\n”,tkn)
fmt.Printf(“对象:\n%v\n”,对象)
}
TL,DR:当您第一次调用Token()
方法时,您会移动(JSON值)开头的偏移量,因此会出现错误
您正在使用此结构():
注意标记状态字段。此值可以是()中的一个:
让我们回到你的代码。您正在调用Token()
方法。此方法获取第一个JSON有效令牌{
,并将令牌状态从tokenObjectValue更改为tokenObjectStart()。现在您处于“对象”状态
如果此时尝试调用Decode()
,则会出现错误(不是在值的开头)。这是因为调用Decode()
允许的tokenState状态是tokenTopValue、tokenarraryStart、tokenarraryValue、tokenObjectValue,即“完整”值,而不是其一部分()
为了避免这种情况,您可以根本不调用Token()
,而是执行以下操作:
dec := json.NewDecoder(strings.NewReader(dataMapFromJson))
objects := make(map[string]*ReadObject)
if err := dec.Decode(&objects); err != nil {
log.Fatalf("failed to parse next symbol: %v", err)
}
fmt.Printf("OBJECTS: \n%v\n", objects)
或者,如果您想逐块读取,您可以继续调用Token()
,直到达到“full”值。然后对该值调用Decode()
(我想应该可以了)。在第一次调用dec.Token()
消耗初始后,您必须:
- 使用
dec.Token()
提取下一个密钥
- 提取密钥后,可以调用
dec.Decode(&nextObject)
对条目进行解码
示例代码:
for dec.More() {
key, err := dec.Token()
if err != nil {
// handle error
}
var val interface{}
err = dec.Decode(&val)
if err != nil {
// handle error
}
fmt.Printf(" %s : %v\n", key, val)
}
你可以一块一块地加载文件,手动查找每个元素,提取并解析它。你想让我演示一下吗?如果你已经有了一个很好的示例。如果没有–不用担心
dec := json.NewDecoder(strings.NewReader(dataMapFromJson))
objects := make(map[string]*ReadObject)
if err := dec.Decode(&objects); err != nil {
log.Fatalf("failed to parse next symbol: %v", err)
}
fmt.Printf("OBJECTS: \n%v\n", objects)
for dec.More() {
key, err := dec.Token()
if err != nil {
// handle error
}
var val interface{}
err = dec.Decode(&val)
if err != nil {
// handle error
}
fmt.Printf(" %s : %v\n", key, val)
}