如何跳过JSON对象流中的'noise'?

col*_*tor 2 io parsing json go

尝试获取以下代码以跳过JSON数据对象流中的解析错误噪声.基本上我希望它跳过这些ERROR: ...行并继续下一个可解析的记录.

json.Decoder有一组有限的方法 - 因此不清楚如何向前移动解码器的索引(比如一次一个字节)以移过噪声.

io.Reader有方法可以跳过来说出行的结尾(或者至少尝试跳过一个字符) - 但是这样的操作不会(理解)影响json.Decoder搜索状态.

有干净的方法吗?

https://play.golang.org/p/riIDh9g1Rx

package main

import (
        "encoding/json"
        "fmt"
        "strings"
        "time"
)

type event struct {
        T    time.Time
        Desc string
}

var jsonStream = ` 
{"T":"2017-11-02T16:00:00-04:00","Desc":"window opened"}
{"T":"2017-11-02T16:30:00-04:00","Desc":"window closed"}
{"T":"2017-11-02T16:41:34-04:00","Desc":"front door opened"}
ERROR: retrieving event 1234
{"T":"2017-11-02T16:41:40-04:00","Desc":"front door closed"}
`

func main() {
        jsonReader := strings.NewReader(jsonStream)
        decodeStream := json.NewDecoder(jsonReader)

        i := 0
        for decodeStream.More() {
                i++ 
                var ev event
                if err := decodeStream.Decode(&ev); err != nil {
                        fmt.Println("parse error: %s", err)
                        break
                }   
                fmt.Printf("%3d: %+v\n", i, ev) 
        }   
}
Run Code Online (Sandbox Code Playgroud)

拿到:

  1: {T:2017-11-02 16:00:00 -0400 -0400 Desc:window opened}
  2: {T:2017-11-02 16:30:00 -0400 -0400 Desc:window closed}
  3: {T:2017-11-02 16:41:34 -0400 -0400 Desc:front door opened}
parse error: %s invalid character 'E' looking for beginning of value
Run Code Online (Sandbox Code Playgroud)

想:

  1: {T:2017-11-02 16:00:00 -0400 -0400 Desc:window opened}
  2: {T:2017-11-02 16:30:00 -0400 -0400 Desc:window closed}
  3: {T:2017-11-02 16:41:34 -0400 -0400 Desc:front door opened}
  4: {T:2017-11-02 16:41:40 -0400 -0400 Desc:front door closed}
Run Code Online (Sandbox Code Playgroud)

Adr*_*ian 5

我认为这是"正确"的方法,因为流本身不是有效的JSON(即使没有错误,JSON文档必须有一个根条目,这是一系列无效的根对象),将是预先解析为单独的,有效的JSON文档,并单独解组.使用例如bufio.Scanner丢弃非JSON线和Unmarshal其他正常线逐行读取流.

请参阅此处的工作示例:https://play.golang.org/p/DZrAVmzwr-

  • 无论是字符串还是Web服务都没关系.过程是一样的,扫描仪仍然可以工作.在我的编辑中查看游乐场示例. (2认同)