3

Goでjson構造の入力ストリームを扱っています。標準入力で別のアプリケーションから入力ストリームを受信しましたが、通信プロトコルを変更できません。

私が抱えている問題は、すべてのjson構造がjson以外の文字列行で終了していることです: "end" (引用符なし)。

Golang エンコーダー/json パッケージを使用して、stdin から受け取った json をデコードしています。問題は、デコーダーがメッセージで2回目に呼び出したときにエラーを生成することです:「値の先頭を探している無効な文字 'e'」。

もちろん、問題は「終了」文字列が json エンコードされていないことです。Go の json デコーダーにこの文字列をスキップさせる方法を知りたいですか?

入力例:

{"command": "ack", "id": "1231231"}
end
{"command": "fail", "id": "1231231"}
end
{
    "command": "log",
    // the message to log
    "msg": "hello world!"
}
end

私が試したこと:

  • 私は宣言しました: endStr := make([]byte, 10)
  • fmt.Fscanf(os.Stdin, "%s", endStr) を使用して文字列を読み取ろうとしましたが、データが読み取られません。
  • os.Stdin.Read(endStr) を使用しようとしましたが、データも返されません。
  • 最初の json 構造を読み取った後、dec.Buffered() は「終了」文字列を含む io.Reader を返しますが、デコーダーにこれをスキップするように指示する方法がわかりません。

どんな助けでも大歓迎です。

4

4 に答える 4

0

JSON オブジェクトを 1 行に制限できる場合は、入力を行ごとに分割し、非整列化されていないものを無視するだけです。ここに小さなコードがあります。

package main

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

var input = `{"command": "ack", "id": "1231231"}
end
{"command": "fail", "id": "1231231"}
end
`

type Obj struct {
    Command string
    Msg     string
    Id      string
}

func DoSomethingCool(o Obj) {
    // Do something cool here
    fmt.Println(o)
}

func main() {
    inputs := strings.Split(input, "\n")
    for _, v := range inputs {
        var obj Obj
        if err := json.Unmarshal([]byte(v), &obj); err == nil {
            DoSomethingCool(obj) // Got a valid JSON
        }
    }
}
于 2013-07-17T20:58:16.247 に答える