golang json decoder and eof
tl;dr;
json.Decoder は EOF を検出するとその後 decode を行わなくなる。
この挙動は tail しつつデコードを続けるような要件と合わない。
詳細
ファイルを tail しつつ、1行毎に json が追記されるようフォーマットを decode したいと考えていた。
以下の様なコードを書くイメージ。
f, _ := os.Open("./file.json") dec := json.NewDecoder(f) v := SomeStruct{} for { dec.Decode(&v) }
しかし json.Decoder は一度末尾まで到達し EOF を検出すると、内部でエラーが発生したことを覚えているため、その後デコードしなくなってしまう。
つまり追記分が一切デコードされなかった。
読み込み部分は自作する必要がありそうなので以下のようなコードを書いて解決した。
これもイメージ、コンパイルは通らないが処理の内容は伝わると思う。
(実際には ReadLine の prefix とか見ないとダメだが長くなるので省略した)
f, _ := os.Open("./file.json") r := bufio.NewReader(f) v := SomeStruct{} var buf bytes.Buffer for { l, _, err := r.ReadLine() if err != nil{ if err == io.EOF{ // 追記待ちでビジーループするので適当に sleep する time.Sleep(time.Second) continue } return err } json.Unmarshal(l, &v) }
これで追記されていくファイルを tail しながら、内容の json をデコードできる。