【发布时间】:2011-11-23 16:16:40
【问题描述】:
我有一个使用BinaryFormatter 序列化数据的应用程序。将成员添加到从一个版本序列化到下一个版本的类中,而不更改类名。添加了代码以处理旧序列化文件中可能缺少添加的成员:
private void readData(FileStream fs, SymmetricAlgorithm dataKey)
{
CryptoStream cs = null;
try
{
cs = new CryptoStream(fs, dataKey.CreateDecryptor(),
CryptoStreamMode.Read);
BinaryFormatter bf = new BinaryFormatter();
string string1 = (string)bf.Deserialize(cs);
// do stuff with string1
bool bool1 = (bool)bf.Deserialize(cs);
// do stuff with bool1
ushort ushort1 = (ushort)bf.Deserialize(cs);
// do stuff with ushort1
// etc. etc. ...
// this field was added later, so it may not be present
// in the serialized binary data. Check for it, and if
// it's not there, do some default behavior
NewStuffIncludedRecently newStuff = null;
try
{
newStuff = (NewStuffIncludedRecently)bf.Deserialize(cs);
}
catch
{
newStuff = null;
}
_newStuff = newStuff != null ?
new NewStuffIncludedRecently(newStuff) :
new NewStuffIncludedRecently();
}
catch (Exception e)
{
// ...
}
finally
{
// ...
}
}
我现在的意思是,我真的很想冲洗并与我想添加的另一个成员重复,这意味着我将添加另一个字段和 try-catch 块,类似于NewStuffIncludedRecently.
我曾想过只制作整个类[Serializable],但这不会破坏与旧序列化数据的兼容性吗?
我主要担心的是我不清楚反序列化是如何工作的。如果我添加与上述类似的另一个可选字段的处理,它会起作用吗?为了更好地处理这些更改,我还有哪些其他选择?
一如既往地提前致谢。
【问题讨论】:
-
使用 binaryformatter 逐字段序列化感觉就像在大小上具有极大的开销。如果您想逐字段进行序列化,您应该只使用二进制编写器。我建议为旧版本 X 保留旧的序列化方案,并将任何新版本传递给基于 DataContracts 和/或协议缓冲区的方案。
-
确实; BinaryFormatter 在版本控制时可能是一个巨大的痛苦;基于合约的序列化器往往更友好(XmlSerializer、DataContractSerializer、protobuf-net 等)。
标签: c# .net deserialization binaryformatter optional