我正在尝试使用Avro的对象容器文件格式和https://github.com/linkedin/goavro.我认为我对一个对象的编码是正确的。但当我试图解码它时,消息似乎是空的。下面的代码演示了这个问题。
package main
import (
"bytes"
"errors"
"fmt"
"github.com/linkedin/goavro/v2"
)
type Animal struct {
Name string
}
func serialize(schema string, msg interface{}) ([]byte, error) {
buf := bytes.NewBuffer(nil)
ocfw, err := goavro.NewOCFWriter(goavro.OCFConfig{
W: buf,
Schema: schema,
})
if err != nil {
return nil, err
}
in, ok := msg.(Animal)
if !ok {
return nil, errors.New("not an animal")
}
out := map[string]interface{}{}
if in.Name == "" {
out["Name"] = goavro.Union("null", nil)
} else {
out["Name"] = goavro.Union("string", in.Name)
}
w := []map[string]interface{}{out}
if err := ocfw.Append(w); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
func deserialize(b []byte) (interface{}, error) {
var msgs []interface{}
ocfr, err := goavro.NewOCFReader(bytes.NewReader(b))
if err != nil {
return nil, err
}
for ocfr.Scan() {
v, err := ocfr.Read()
if err != nil {
return nil, err
}
fmt.Println("read:", v)
//TODO: Once the value is being read as not nil, decode it into out.
out := Animal{}
msgs = append(msgs, out)
}
if err := ocfr.Err(); err != nil {
return nil, err
}
return msgs, nil
}
func main() {
schema := `{"type":"record","name":"Animal","fields":[{"name":"name","type":["null","string"],"default":null}]}`
msg := Animal{
Name: "Tiger",
}
encoded, err := serialize(schema, msg)
if err != nil {
panic(err)
}
fmt.Println("encoded:", encoded)
decoded, err := deserialize(encoded)
if err != nil {
panic(err)
}
fmt.Println("decoded:", decoded)
}
输出为:
encoded: [79 98 106 1 4 22 97 118 114 111 46 115 99 104 101 109 97 200 1 123 34 116 121 112 101 34 58 34 114 101 99 111 114 100 34 44 34 110 97 109 101 34 58 34 65 110 105 109 97 108 34 44 34 102 105 101 108 100 115 34 58 91 123 34 110 97 109 101 34 58 34 110 97 109 101 34 44 34 116 121 112 101 34 58 91 34 110 117 108 108 34 44 34 115 116 114 105 110 103 34 93 44 34 100 101 102 97 117 108 116 34 58 110 117 108 108 125 93 125 20 97 118 114 111 46 99 111 100 101 99 8 110 117 108 108 0 85 252 58 132 245 55 172 159 242 74 105 116 221 238 89 247 2 2 0 85 252 58 132 245 55 172 159 242 74 105 116 221 238 89 247]
read: map[name:<nil>]
decoded: [{}]
我希望以read:
开头的行是map[name:Tiger]
。我哪里错了?
Case是罪魁祸首。Name
在序列化时应该是name
。以下块
if in.Name == "" {
out["Name"] = goavro.Union("null", nil)
} else {
out["Name"] = goavro.Union("string", in.Name)
}
需要
if in.Name == "" {
out["name"] = goavro.Union("null", nil)
} else {
out["name"] = goavro.Union("string", in.Name)
}