Go-yaml控制字符不允许出现的错误。

huangapple go评论139阅读模式
英文:

Go-yaml control characters are not allowed error

问题

我正在尝试制作一个非常简单的SSH地址簿程序。它会获取一些关于SSH地址的信息,并将其存储在一个YAML文档中。我这样做部分是为了学习一些关于Go的知识,但是我遇到了一个小问题。我可以将数据序列化并将文档放入文件中,但是当我尝试读取它时,我遇到了这个错误:yaml: control characters are not allowed

我不确定这个错误消息的含义,搜索也没有得到有用的结果。有什么想法吗?

这些是我用来组织数据的结构体:

type EntriesList struct {
    SSHEntries []SSHEntry `yaml:"sshentries"`
}

type SSHEntry struct {
    Name    string  `yaml:"name"`
    Command SSHCmd  `yaml:"command"`
}

type SSHCmd struct {
    Addr  string `yaml:"addr"`
    Port  int    `yaml:"port"`
    Uname string `yaml:"uname"`
}

它将我的数据格式化为:

---
entrieslist:
 - name: entry1
   command:
     addr: somewhere
     port: 22
     uname: someone
 - name: entry2 ... etc

我使用一个YAML验证器检查了上述格式,它是合法的YAML。这是我用来读取文件的函数:

// CONF是文件的路径
func readConf(CONF string) *EntriesList {
    configFile := openConfigFile(CONF)
    defer configFile.Close()

    buffer := make([]byte, 512, 512)
    _, err := configFile.Read(buffer)
    check(err)

    var entries EntriesList
    err = yaml.Unmarshal(buffer, &entries)
    data, _ := yaml.Marshal(entries)
    fmt.Println(string(data))

    return &entries
}

希望对你有帮助!

英文:

I'm trying to make a really simple ssh address book program. Takes some info about ssh addresses and stores them in a yaml document. I'm doing it partly to learn a bit about Go and am having a small problem. I can serialize the data and put a document into a file but I'm getting this error when I try to read it back:
yaml: control characters are not allowed

I'm not sure what this error message means, googling didn't yield any helpful results. Any ideas?

These are the structs I'm using to organize the data:

type EntriesList struct {
    SSHEntries []SSHEntry `yaml:"sshentries"`
}   
    
type SSHEntry struct {
    Name    string `yaml:"name"`
    Command SSHCmd `yaml:"command"`
}   
    
type SSHCmd struct {
    Addr  string `yaml:"addr"`
    Port  int    `yaml:"port"`
    Uname string `yaml:"uname"`
}   

The format it puts my data into is:

---
entrieslist:
 - name: entry1
   command:
     addr: somewhere
     port: 22
     uname: someone
 - name: entry2 ... etc 

I checked this ^^ with a YAML validator and it is legal YAML.
Here is my function to read the file:

// CONF is the path to the file
func readConf(CONF string) *EntriesList {
    configFile := openConfigFile(CONF)
    defer configFile.Close()

    buffer := make([]byte, 512, 512)
    _, err := configFile.Read(buffer)
    check(err)

    var entries EntriesList
    err = yaml.Unmarshal(buffer, &entries)
    data, _ := yaml.Marshal(entries)
    fmt.Println(string(data))

    return &entries
}

答案1

得分: 6

搞定了,问题是我的缓冲区太大了。如果你有一个太大的 []byte,go-yaml 会将这些额外的字节读取为字符并抛出错误。我修改了我的代码:

func readConf(CONF string) *EntriesList {
    confiFile, err := ioutil.ReadFile(CONF)
    check(err)
    var entries EntriesList
    err = yaml.Unmarshal(confiFile, &entries)
    check(err)
    return &entries
}

然后它按预期工作了。

英文:

Figured it out, the problem was that my buffer was too big. If you have a []byte that is too big then go-yaml will read those extra bytes as characters and throw errors. I changed my code to :

func readConf(CONF string) *EntriesList {
    confiFile, err := ioutil.ReadFile(CONF)
    check(err)
    var entries EntriesList
    err = yaml.Unmarshal(confiFile, &entries)
    check(err)
    return &entries
}

And it worked as expected.

答案2

得分: 1

从听起来的声音,你在 https://github.com/go-yaml/yaml/blob/53feefa2559fb8dfa8d81baad31be332c97d6c77/readerc.go#L347 处遇到了错误块,看起来它应该还告诉你偏移量(文件中遇到问题字符的位置)和字符代码。如果这些信息足以解决你的问题,那太好了。然而,如果 yaml 库输出的已验证的 yaml 不适合作为输入,你应该在 Github 上向维护者提交一个问题,链接是 https://github.com/go-yaml/yaml/issues

英文:

From the sounds of it, you're hitting the error block at https://github.com/go-yaml/yaml/blob/53feefa2559fb8dfa8d81baad31be332c97d6c77/readerc.go#L347 , and it looks like that should also be telling you the offset (where in the file it's hitting the problematic character) and character code. If that info is enough to solve your problem, then great. If, on the other hand, the yaml library is spitting out validated yaml that it is not comfortable accepting as input, you should open an issue with the maintainer on Github at https://github.com/go-yaml/yaml/issues

答案3

得分: 0

我知道这个回答有点晚,但是使用主要问题中的函数,也可以使用读取到缓冲区的字节数来切片数据。

// CONF 是文件的路径
func readConf(CONF string) *EntriesList {
    configFile := openConfigFile(CONF)
    defer configFile.Close()

    buffer := make([]byte, 512, 512)
    n, err := configFile.Read(buffer)
    check(err)

    var entries EntriesList
    err = yaml.Unmarshal(buffer[:n], &entries)
    data, _ := yaml.Marshal(entries)
    fmt.Println(string(data))

    return &entries
}
英文:

I know this came over-late, but using the function from the main question, one can also use the number of bytes read into the buffer to slice the data.

// CONF is the path to the file
func readConf(CONF string) *EntriesList {
    configFile := openConfigFile(CONF)
    defer configFile.Close()

    buffer := make([]byte, 512, 512)
    n, err := configFile.Read(buffer)
    check(err)

    var entries EntriesList
    err = yaml.Unmarshal(buffer[:n], &entries)
    data, _ := yaml.Marshal(entries)
    fmt.Println(string(data))

    return &entries
}

huangapple
  • 本文由 发表于 2015年11月15日 16:30:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/33717799.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定