英文:
Go: Is it safe to use gob package to save data to file for later use?
问题
我目前正在将一个结构体保存到文件中,以便后续使用。我使用gob实现了加载和保存的功能,代码如下:
func (t *Object) Load(filename string) error {
fi, err := os.Open(filename)
if err != nil {
return err
}
defer fi.Close()
fz, err := gzip.NewReader(fi)
if err != nil {
return err
}
defer fz.Close()
decoder := gob.NewDecoder(fz)
err = decoder.Decode(&t)
if err != nil {
return err
}
return nil
}
func (t *Object) Save(filename string) error {
fi, err := os.Create(filename)
if err != nil {
return err
}
defer fi.Close()
fz := gzip.NewWriter(fi)
defer fz.Close()
encoder := gob.NewEncoder(fz)
err = encoder.Encode(t)
if err != nil {
return err
}
return nil
}
我的担忧是,Go语言可能会更新,改变对数据进行编码和解码的方式。如果发生这种情况,使用新版本Go编译的应用程序将无法加载之前版本保存的文件。这将是一个重大问题,但我不确定这是否是一个现实的担忧。
所以,有人知道我是否可以安全地保存和加载gob编码的数据,并期望在Go更新后仍然能正常工作吗?
如果不能,有什么更好的替代方案吗?如果我将gob.NewDecoder
和gob.NewEncoder
更改为xml.NewDecoder
和xml.NewEncoder
,我的函数是否仍然能正常工作?(XML编码器是否以与gob相同的方式对结构体进行编码和解码,即无需告诉它们结构体的结构?)
英文:
I'm currently saving a struct to file so it can be loaded and later used by implementing gob, as follows:
func (t *Object) Load(filename string) error {
fi, err := os.Open(filename)
if err !=nil {
return err
}
defer fi.Close()
fz, err := gzip.NewReader(fi)
if err !=nil {
return err
}
defer fz.Close()
decoder := gob.NewDecoder(fz)
err = decoder.Decode(&t)
if err !=nil {
return err
}
return nil
}
func (t *Object) Save(filename string) error {
fi, err := os.Create(filename)
if err !=nil {
return err
}
defer fi.Close()
fz := gzip.NewWriter(fi)
defer fz.Close()
encoder := gob.NewEncoder(fz)
err = encoder.Encode(t)
if err !=nil {
return err
}
return nil
}
My concern is that Go might be updated in a way that changes the way that gobs of data are encoding and decoded. If this happens then the version of my app compiled with the new version of Go would not be able to load files saved from the previous version. This would be a major issue but I'm not sure if its a realistic concern or not.
So does anyone know if I can consider it safe to save and load gob encoding data like this and expect it to still work when Go is updated?
If not, what would be the best alternative? Would my function still work if I changed gob.NewDecoder
and gob.NewEncoder
to xml.NewDecoder
and xml.NewEncoder
? (Does the XML encoder encode and decode structs in the same way as gob, i.e. without me having to tell it what they look like?)
答案1
得分: 7
GobEncoder类型的文档确实提到:
注意:由于gob可以永久存储,因此保证
GobEncoder
使用的编码在软件演进过程中是稳定的是一个很好的设计。例如,GobEncode
在编码中包含一个版本号可能是有意义的。
但这仅适用于自定义编码器。
对于Go提供的编码器,兼容性在源代码级别上得到保证:不会对任何Go 1点版本进行不兼容的更改。
这意味着gob应该会继续像现在这样工作。
还有一个不同且强大的解决方案,就是像“ugorji/go/codec”这样的项目:
高性能和功能丰富的Go库,提供对不同序列化格式的编码/解码支持。
支持的序列化格式有:
msgpack
:https://github.com/msgpack/msgpackbinc
:http://github.com/ugorji/binc
但除非你需要这些特定的格式,否则gob应该已经足够了。
英文:
The documentation for the type GobEncoder does mention:
> Note: Since gobs can be stored permanently, It is good design to guarantee the encoding used by a GobEncoder
is stable as the software evolves.
For instance, it might make sense for GobEncode
to include a version number in the encoding.
But that applies to custom encoder.
For the one provided with go, the compatibility is guarantee at source level: Backwards-incompatible changes will not be made to any Go 1 point release.
That should mean gob should continue to work as it does now.
A different and robust solution exists with projects like "ugorji/go/codec":
> High Performance and Feature-Rich Idiomatic Go Library providing encode/decode support for different serialization formats.
>
> Supported Serialization formats are:
>
> - msgpack
: https://github.com/msgpack/msgpack
> - binc
: http://github.com/ugorji/binc
But unless you need those specific formats, gob should be enough.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论