ISerialized 和向后兼容性
我必须使用一个旧应用程序,该应用程序使用binaryFormatter将应用程序数据序列化到文件流中(例如在名为“data.oldformat”的文件中) 没有任何优化,主类已标记有属性
<serializable()>public MainClass
.......
end class
和序列化代码。
dim b as new binaryformatter
b.serialize(mystream,mymainclass)
为了优化序列化/反序列化过程,我只是让该类实现 ISerialized 接口,并编写了一些优化的序列化例程。
<serializable()>public MainClass
implements ISerializable
.......
end class
优化效果非常好,但我必须找到一个重新获取旧文件中的数据以实现向后兼容性的方法。
我怎样才能做到这一点?
皮尔路易吉
I have to work an an old application that used binaryFormatter to serialize application data into filestream (say in a file named "data.oldformat")
without any optimizazion the main class has been marked with attribute
<serializable()>public MainClass
.......
end class
and the serialization code
dim b as new binaryformatter
b.serialize(mystream,mymainclass)
In an attempt to optimize the serialization/deserialization process I simply made the class implement the ISerializable interface and wrote some optimized serialization routines
<serializable()>public MainClass
implements ISerializable
.......
end class
The optimization works really well but I MUST find a way to reatrive the data inside the old files for backward compatibility.
How can I do that??
Pierluigi
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
stmax 有一个很好的答案,但是我会像这样实现它,它使用
SerializationEntry.GetEnumerator()
而不是try/catch
。这种方式更加干净并且速度明显更快。我更喜欢使用 .FirstOrDefault() 的 LINQ 版本,但 SerializationInfo 没有实现 IEnumerable - 表面上,奇怪的是,它甚至没有实现旧的 IEnumerable 接口。
stmax has an excellent answer, however I would implement it like this, which uses
SerializationEntry.GetEnumerator()
instead oftry/catch
. This way is cleaner and significantly faster.I would prefer a LINQ version using .FirstOrDefault(), but SerializationInfo does not implement IEnumerable - in face, weirdly enough, it doesn't even implement the old IEnumerable interface.
由于您已经实现了 ISerialized 接口,因此您可能也已经添加了所需的构造函数:
您可以使用传递给构造函数的信息对象从序列化文件中检索数据。 默认情况下(即,当没有实现 ISerializable 时),字段名称在序列化期间用作标识符。因此,如果您的旧类有一个字段“int x”,您可以使用以下方法反序列化:
对于较新的版本,我通常在序列化期间添加一个“版本”条目,如下所示:
在反序列化期间,您可以检查此版本条目并相应地反序列化:
我还没有编译该代码,可能包含拼写错误。
希望有帮助。
since you've already implemented the ISerializable interface, you've probably also already added the required constructor:
you can use the info-object passed to the constructor to retrieve data from the serialized file. by default (i.e. when no ISerializable is implemented), the fields names are used as identifiers during serialization. so if your old class had a field "int x" you can deserialize this using:
for newer versions i normally add a "version" entry during serialization, like this:
during deserialization you can check this version entry and deserialize accordingly:
i haven't compiled that code, might contain typos.
hope that helps.
只需尝试到目前为止您一直在做的同样的事情
实现 ISerialized 并没有改变您的原始类,基本上您只是添加了一些方法
Just try the same thing you've been doing so far
Implementing ISerializable didn't change your original class, basically you've just added some methods
序列化对象时添加一个额外的 Version 字段(这不会增加太多开销)。然后在 GetObjectData 方法中,尝试首先检索版本字段,并根据该字段是否存在(通过捕获 SerializationException)以旧方式或新方式反序列化。旧方法只是序列化所有数据,因此您应该能够为所有字段调用 Get...。
When serializing your objects add an additional Version field (this shouldn't add too much overhead). Then in your GetObjectData method, try to retrieve the version field first and based on whether this exists or not (by catching the SerializationException) deserialize the old way or the new way. The old way will have just serialized all data so you should just be able to call Get... for all fields.
您之前的代码应该可以工作。你有例外吗?
尝试使用新的构造函数:
Your previous code should work. Do you get an exception?
Try to use new constructor: