GoでJSONデータをメモリ効率よく処理する

Go

GoでJSONを扱う場合、”encoding/json”パッケージを使います。

よく使うのは、MarshalとUnmarshalの2つですが、今回は以下のメソッドを使用していきます。

  • メモリに保存せずストリームとして処理する
    • NewEncoder
    • NewDecoder
package main

import (
	"encoding/json"
	"os"
)

type User struct {
	Name  string `json:"name"`
	Age   int    `json:"age"`
	Email string `json:"email"`
}

func main() {
	user := User{
		Name:  "Test",
		Age:   25,
		Email: "test@example.com",
	}

	file, err := os.Create("user.json")
	if err != nil {
		panic(err)
	}
	defer file.Close()

    // ストリームとして逐次処理してファイルに書き込む
	encoder := json.NewEncoder(file)
	err = encoder.Encode(user)
	if err != nil {
		panic(err)
	}
}
package main

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

type User struct {
	Name  string `json:"name"`
	Age   int    `json:"age"`
	Email string `json:"email"`
}

func main() {
	file, err := os.Open("user.json")
	if err != nil {
		panic(err)
	}

	var user User

    // ファイルから読み込んだJSONデータをそのまま構造体に入れる
	decoder := json.NewDecoder(file)
	err = decoder.Decode(&user)
	if err != nil {
		panic(err)
	}

	fmt.Printf("Name: %s\n", user.Name)
	fmt.Printf("Age: %d\n", user.Age)
	fmt.Printf("Email: %s\n", user.Email)
}

このようにNewEncoder、NewDecoderを使用すると、MarshalやUnmarshalを使っていたときのように、構造体をbyteに変換したり、JSON文字列をbyteに変換する必要がなく、メモリに保存しなくていいので、メモリの消費が抑えられます。