Декодирование потока JSON, который не заключен в квадратные скобки? - PullRequest
0 голосов
/ 19 января 2019

Я пытаюсь декодировать поток JSON из файла. Файл представляет собой разделенные строкой JSON-объекты. Но он не отформатирован в скобках массива, окружающих объекты, поэтому я не могу понять, как использовать encoding/json потоковый декодер.

Я получаю ошибку not at beginning of value, потому что нет открывающей скобки.

package main

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

func main() {

    // My data is missing opening and closing brackets around the jsonStream string.
    // [
    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))

    // read open bracket -- this fails (no bracket)
    t, err := dec.Token()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%T: %v\n", t, t)

    // while the array contains values
    for dec.More() {
        var m Message
        // decode an array value (Message)
        err := dec.Decode(&m)
        if err != nil {
            log.Fatal(err)
        }

        fmt.Printf("%v: %v\n", m.Name, m.Text)
    }

    // read closing bracket -- this also would fail (no bracket)
    t, err = dec.Token()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%T: %v\n", t, t)

}

Удаление проверок ошибок dec.Token () также не работает. Я думаю, парсер не ожидает увидеть объекты до того, как он увидит открытую скобку массива?

Есть ли какое-то решение?

Ответы [ 2 ]

0 голосов
/ 20 января 2019

Я закончил тем, что сделал это:

f, err := os.Open(fname)
if err != nil {
    // handle error
}
d := json.NewDecoder(f)
for {
    var v ValueTypeToUnmarshalTo
    if err := d.Decode(&v); err == io.EOF {
        break // done decoding file
    } else if err != nil {
        // handle error
    }
    // do something with v
}

Декодер, кажется, игнорирует переводы строки, поэтому нет даже необходимости использовать потоковый декодер.Это только в том случае, если у вас есть массив JSON.

Взято из части этого ответа: https://stackoverflow.com/a/34388102

Спасибо за помощь!

0 голосов
/ 19 января 2019

Одним из предложений является использование трубы, а также добавление и добавление [].

.
reader := strings.NewReader(jsonStream)

pr, pw := io.Pipe()

go func() {
    pw.Write([]byte(`[`))
    io.Copy(pw, reader)
    pw.Write([]byte(`]`))
}()

dec := json.NewDecoder(pr)

Вы должны добавить некоторую обработку ошибок.

См. https://play.golang.org/p/Oogu_NdAUyR для всего этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...