无法使用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) 
    } 
} 
+1

,为什么你不使用的嵌套地图。可能输入需要作为嵌套地图。 –

+0

@SimoEndre:根据https://blog.golang.org/go-maps-in-action博客,如果您有映射的嵌套地图类型结构,他们建议使用Struct。 但是我是Go的新手,我不确定我是否可以使用该结构。 它没有给出任何编译错误,但它没有保存长字符串。 – rohan

没有什么特殊的编码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