複数のjsonオブジェクトを含むunmarshaljsonファイル(無効なjsonファイル)[重複]

Nov 20 2020

次の内容のjsonファイル(file.json)があります。

file.json:

{"job": "developer"}
{"job": "taxi driver"}
{"job": "police"}

ファイルの内容は上記とまったく同じです(有効なjsonファイルではありません)

コードでデータを使用したいのですが、これをアンマーシャルできません

回答

Зелёный Nov 20 2020 at 16:00

文字列を1行ずつ読み取り、マーシャリングを解除できます。

package main

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

type j struct {
    Job string `json:"job"`
}

func main() {
    payload := strings.NewReader(`{"job": "developer"}
{"job": "taxi driver"}
{"job": "police"}`)
    fscanner := bufio.NewScanner(payload)
    for fscanner.Scan() {
        var job j
        err := json.Unmarshal(fscanner.Bytes(), &job)
        if err != nil {
            fmt.Printf("%s", err)
            continue
        }
        fmt.Printf("JOB %+v\n", job)
    }
}

出力:

JOB {Job:developer}
JOB {Job:taxi driver}
JOB {Job:police}

4 icza Nov 20 2020 at 15:55

持っているのは、単一のJSONオブジェクトではなく、一連の(無関係な)JSONオブジェクトです。json.Unmarshal()複数の(独立した)JSON値を含むものをアンマーシャリングするために使用することはできません。

json.Decoderソースから複数のJSON値(オブジェクト)を1つずつデコードするために使用します。

例えば:

func main() {
    f := strings.NewReader(file)
    dec := json.NewDecoder(f)

    for {
        var job struct {
            Job string `json:"job"`
        }
        if err := dec.Decode(&job); err != nil {
            if err == io.EOF {
                break
            }
            panic(err)
        }
        fmt.Printf("Decoded: %+v\n", job)
    }
}

const file = `{"job": "developer"}
{"job": "taxi driver"}
{"job": "police"}`

どの出力(Go Playgroundで試してください):

Decoded: {Job:developer}
Decoded: {Job:taxi driver}
Decoded: {Job:police}

このソリューションは、JSONオブジェクトがソースファイルで複数の行を占める場合、または同じ行に複数のJSONオブジェクトがある場合でも機能します。

関連項目を参照してください:次の方法でexec.Command出力の出力を取得していました。その出力から必要なデータを取得したい