14
11

More than 5 years have passed since last update.

Golangでyamlファイルを読み書きする。

Last updated at Posted at 2019-01-27

 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

以上です。

14
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
11