无法使用gob正确地在文件中存储数据
问题描述:
当我尝试使用gob
编码器将map[mapKey]string
类型的映射保存到文件中时,它不会将字符串保存在文件中。无法使用gob正确地在文件中存储数据
这里mapKey
是struct和map的值是长json字符串。
type mapKey struct{
Id1 string
Id2 string
}
每当我使用的,而不是像结构嵌套地图:
var m = make(map[string]map[string]string)
这是工作的罚款,并适当保存字符串。我不知道我在这里失去了什么。
码编码,解码,并将其保存在文件中:
func Save(path string, object interface{}) error {
file, err := os.Create(path)
if err == nil {
encoder := gob.NewEncoder(file)
encoder.Encode(object)
}
file.Close()
return err
}
// Decode Gob file
func Load(path string, object interface{}) error {
file, err := os.Open(path)
if err == nil {
decoder := gob.NewDecoder(file)
err = decoder.Decode(object)
}
file.Close()
return err
}
func Check(e error) {
if e != nil {
_, file, line, _ := runtime.Caller(1)
fmt.Println(line, "\t", file, "\n", e)
os.Exit(1)
}
}
答
没有什么特殊的编码map[mapKey]string
类型的值。
查看它使用指定的读取器/写入器这个非常简单的工作示例:
func save(w io.Writer, i interface{}) error {
return gob.NewEncoder(w).Encode(i)
}
func load(r io.Reader, i interface{}) error {
return gob.NewDecoder(r).Decode(i)
}
测试其与内存中的缓冲液(bytes.Buffer
):
m := map[mapKey]string{
{"1", "2"}: "12",
{"3", "4"}: "34",
}
fmt.Println(m)
buf := &bytes.Buffer{}
if err := save(buf, m); err != nil {
panic(err)
}
var m2 map[mapKey]string
if err := load(buf, &m2); err != nil {
panic(err)
}
fmt.Println(m2)
输出按预期(尝试在Go Playground):
map[{1 2}:12 {3 4}:34]
map[{1 2}:12 {3 4}:34]
你有工作但知道您必须用指针值调用Load()
(否则Decoder.Decode()
将无法修改其值)。
另外几件事情,以改善它:
- 在你的榜样你吞咽通过
Encoder.Encode()
(检查它,你会看到的问题是什么返回error
;一个常见的问题是使用结构mapKey
没有导出字段,在这种情况下会返回gob: type main.mapKey has no exported fields
的错误)。 - 此外,您应该致电
File.Close()
作为延期功能。 - 此外,如果打开文件失败,您应该早返回,而不应关闭文件。
这是你的代码的修正版本:
func Save(path string, object interface{}) error {
file, err := os.Create(path)
if err != nil {
return err
}
defer file.Close()
return gob.NewEncoder(file).Encode(object)
}
func Load(path string, object interface{}) error {
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
return gob.NewDecoder(file).Decode(object)
}
测试它:
m := map[mapKey]string{
{"1", "2"}: "12",
{"3", "4"}: "34",
}
fmt.Println(m)
if err := Save("testfile", m); err != nil {
panic(err)
}
var m2 map[mapKey]string
if err := Load("testfile", &m2); err != nil {
panic(err)
}
fmt.Println(m2)
产量预期:
map[{1 2}:12 {3 4}:34]
map[{1 2}:12 {3 4}:34]
+0
会建议检查您是否使用指针作为icza在这里描述 - 其他非常好的建议。 – TehSphinX
,为什么你不使用的嵌套地图。可能输入需要作为嵌套地图。 –
@SimoEndre:根据https://blog.golang.org/go-maps-in-action博客,如果您有映射的嵌套地图类型结构,他们建议使用Struct。 但是我是Go的新手,我不确定我是否可以使用该结构。 它没有给出任何编译错误,但它没有保存长字符串。 – rohan