【问题标题】:How to read a YAML file如何读取 YAML 文件
【发布时间】:2015-09-05 23:47:11
【问题描述】:

我在读取 YAML 文件时遇到问题。我认为这是文件结构中的一些东西,但我不知道是什么。

YAML 文件:

conf:
  hits:5
  time:5000000

代码:

type conf struct {
    hits int64 `yaml:"hits"`
    time int64 `yaml:"time"`
}


func (c *conf) getConf() *conf {

    yamlFile, err := ioutil.ReadFile("conf.yaml")
    if err != nil {
        log.Printf("yamlFile.Get err   #%v ", err)
    }
    err = yaml.Unmarshal(yamlFile, c)
    if err != nil {
        log.Fatalf("Unmarshal: %v", err)
    }

    return c
}

【问题讨论】:

  • 您看到的错误是什么?
  • @AmitKumarGupta 我没有收到任何错误,只是空结构
  • 您认为这可能与您的问题相关吗?另外,您可以粘贴重现问题的完整代码吗? package main,您正在导入什么文件,main 函数等,以便人们可以轻松地帮助您复制粘贴代码并在本地运行它。考虑添加便于人们帮助您的信息和代码,因为您希望人们帮助您。
  • 如前所述,任何通过反射(JSON、XML、YAML 解组等)设置字段的东西都只能在导出的字段上工作。

标签: go yaml


【解决方案1】:

你的 yaml 文件必须是

hits: 5
time: 5000000

您的代码应如下所示:

package main

import (
    "fmt"
    "gopkg.in/yaml.v2"
    "io/ioutil"
    "log"
)

type conf struct {
    Hits int64 `yaml:"hits"`
    Time int64 `yaml:"time"`
}

func (c *conf) getConf() *conf {

    yamlFile, err := ioutil.ReadFile("conf.yaml")
    if err != nil {
        log.Printf("yamlFile.Get err   #%v ", err)
    }
    err = yaml.Unmarshal(yamlFile, c)
    if err != nil {
        log.Fatalf("Unmarshal: %v", err)
    }

    return c
}

func main() {
    var c conf
    c.getConf()

    fmt.Println(c)
}

主要错误是结构的大写字母。

【讨论】:

  • 这对我不起作用。我需要将err = yaml.Unmarshal(yamlFile, c) 行更改为err = yaml.Unmarshal(yamlFile, &c),即传递指针而不是值。我不知道为什么。
  • 它通过类型 conf 结构绑定到代码。如果配置文件更改,将无法重用。有没有什么是动态的,无需在代码中定义结构?
  • @joelfischerr 你说得对,我必须做出同样的改变才能正常工作。
  • @MopparthyRavindranath 我认为您需要使用接口来执行此操作,但为什么配置文件会更改多次?
【解决方案2】:

使用升级后的 第 3 版 yaml 包。

conf.yaml 文件示例:

conf:
  hits: 5
  time: 5000000
  camelCase: sometext

main.go 文件:

package main

import (
    "fmt"
    "io/ioutil"
    "log"

    "gopkg.in/yaml.v3"
)

type myData struct {
    Conf struct {
        Hits      int64
        Time      int64
        CamelCase string `yaml:"camelCase"`
    }
}

func readConf(filename string) (*myData, error) {
    buf, err := ioutil.ReadFile(filename)
    if err != nil {
        return nil, err
    }

    c := &myData{}
    err = yaml.Unmarshal(buf, c)
    if err != nil {
        return nil, fmt.Errorf("in file %q: %v", filename, err)
    }

    return c, nil
}

func main() {
    c, err := readConf("conf.yaml")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%v", c)
}

运行说明(如果这是您第一次退出标准库):

go mod init example.com/whatever
go get gopkg.in/yaml.v3
cat go.sum
go run .

标签(如 yaml:"field")对于任何全小写的 yaml 密钥标识符都是可选的。对于节目,我已经包含了一个用于 camelCase 标识符的节目。

(令人困惑的是,“yaml”的这种小写行为在标准“json”包中没有。如果您的结构同时用于 JSON 和 YAML 编码,最好在几乎每个领域。冗长,但减少错误。)

【讨论】:

    【解决方案3】:
    package main
    
    import (
        "gopkg.in/yaml.v2"
        "io/ioutil"
        "log"
    )
    
    type someConf struct {
        AccessKeyID     string `yaml:"access_key_id"`
       //...
    }
    
    func getConf(file string, cnf interface{}) error {
       yamlFile, err := ioutil.ReadFile(file)
       if err == nil {
          err = yaml.Unmarshal(yamlFile, cnf)
       }
       return err
    }
    
    func main() {
        cfg := &awsConf{}
        if err := getConf("conf.yml", cfg); err != nil {
            log.Panicln(err)
        }
     }
    

    有史以来最短的 getConf

    【讨论】:

      猜你喜欢
      • 2020-11-09
      • 1970-01-01
      • 2020-06-21
      • 2019-01-09
      • 2015-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-24
      相关资源
      最近更新 更多