Golangでyamlを読み書きする方法をメモっていきます。go-yaml/yamlというライブラリを使用します(https://github.com/go-yaml/yaml)。
go-yaml/yamlパッケージの取得
go getで取ってきましょう↓
go-yaml/yamlを取得
go get go-yaml/yaml
最初はViperというライブラリを使ってみたのですが、これは機能が多すぎて逆に使いづらく(ディスってるわけじゃないのですが)、その内部で使われてる go-yaml/yaml 自体を使った方が簡単でした。
読み込むファイル
読み込むyamlファイルですが、こんな感じとします↓
test.yaml
- first: hello
second: world
- first: hoo
second: var
yamlファイルの読み込み
[]map[string]string にマッピング
[]map[string]stringにマッピングする
package main
import (
"fmt"
"github.com/go-yaml/yaml"
"io/ioutil"
)
func main() {
// test.yamlを []byte として読み込みます。
buf, err := ioutil.ReadFile("./test.yaml")
if err != nil {
fmt.Println(err)
return
}
// []byte を []map[string]string に変換します。
data, err := ReadOnSliceMap(buf)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(data)
}
// yaml形式の[]byteを渡すと[]map[string]stringに変換してくれる関数です。
func ReadOnSliceMap(fileBuffer []byte) ([]map[string]string, error) {
data := make([]map[string]string, 20)
// ここで変換を行っています。
// []byteを渡すとデータ型に合わせて上手い事マッピングしてくれます。
err := yaml.Unmarshal(fileBuffer, &data)
if err != nil {
fmt.Println(err)
return nil, err
}
return data, nil
}
[]struct にマッピング
[]map[string]stringにマッピングする
package main
import (
"fmt"
"github.com/go-yaml/yaml"
"io/ioutil"
)
// マッピングする構造体です。
// どういうわけか、大文字じゃないとダメのようです。
type Test struct {
First string
Second string
}
func main() {
buf, err := ioutil.ReadFile("./test.yaml")
if err != nil {
fmt.Println(err)
return
}
// []byte を []Test に変換します。
data, err := ReadOnStruct(buf)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(data)
}
// yaml形式の[]byteを渡すと[]Testに変換してくれる関数です。
func ReadOnStruct(fileBuffer []byte) ([]Test, error) {
data := make([]Test, 20)
// []map[string]string のときと使う関数は同じです。
// いい感じにマッピングしてくれます。
err := yaml.Unmarshal(fileBuffer, &data)
if err != nil {
fmt.Println(err)
return nil, err
}
return data, nil
}
データをyaml形式でファイルに保存する
データを yaml.marshal で []byte に変換し、それをyamlファイルに書き込むといった感じになります。つまりこんな感じ↓
yaml形式のファイルに保存する
package main
import (
"fmt"
"github.com/go-yaml/yaml"
"io/ioutil"
)
// マッピングする構造体です。
type Test struct {
First string
Second string
}
func main() {
buf, err := ioutil.ReadFile("./test.yaml")
if err != nil {
fmt.Println(err)
return
}
data, err := ReadOnStruct(buf)
if err != nil {
fmt.Println(err)
return
}
// hello を hi に書き換えて保存します。
data[0].First = "hi"
err = WriteOnFile(fileName, data)
if err != nil {
fmt.Println(err)
return
}
}
// yaml形式の[]byteを渡すと[]Testに変換してくれる関数です。
func ReadOnStruct(fileBuffer []byte) ([]Test, error) {
data := make([]Test, 20)
// []map[string]string のときと使う関数は同じです。
// いい感じにマッピングしてくれます。
err := yaml.Unmarshal(fileBuffer, &data)
if err != nil {
fmt.Println(err)
return nil, err
}
return data, nil
}
// ファイル名とデータをを渡すとyamlファイルに保存してくれる関数です。
func WriteOnFile(fileName string, data interface{}) error {
// ここでデータを []byte に変換しています。
buf, err := yaml.Marshal(data)
if err != nil {
return err
}
// []byte をファイルに上書きしています。
err = ioutil.WriteFile(fileName, buf, os.ModeExclusive)
if err != nil {
return err
}
return nil
}
保存するとこんな感じ↓
保存した奴
- first: hi
second: world
- first: hoo
second: var
以上です。