序列化到底在哪里?我读到关于网络上的序列化,我已经知道了
它是一个接口,如果在类中实现,意味着它可以被不同的序列化器自动序列化和反序列化。
给我一个很好的理由,为什么以及何时需要将一个类序列化?假设一旦序列化,究竟发生了什么?
答案 0 :(得分:25)
只要对象需要持久化或传输超出其存在范围,就需要进行序列化。
持久性是指在某处保存对象并稍后以相同状态加载它的能力。例如:
传输是将对象发送到其原始范围之外的能力。例如:
对于其中的每一个,必须有一些串行位表示,可以存储,传递,然后用于重建原始对象。将对象转换为这一系列位的过程称为“序列化”,而将一系列位转换为原始对象的过程称为“反序列化”。
序列化形式的对象的实际表示形式可能因您的目标而异。例如,在C#中,您既有XML序列化(通过XmlSerializer
类)又有二进制序列化(通过使用BinaryFormatter
类)。根据您的需要,您甚至可以编写自己的自定义序列化程序来执行其他工作,例如压缩或加密。如果您需要一种语言和平台无关的序列化格式,您可以尝试Google Protocol Buffers现在有support for .NET(我还没有用过)。
上面提到的XML表示适用于以标准格式存储对象,但根据您的需要,它可能是冗长和缓慢的。二进制表示节省了空间,但不像XML那样可以跨语言和运行时移植。重要的是串行器和解串器必须相互理解。当您开始引入向后和向前兼容性和版本控制时,这可能是一个问题。
潜在的序列化兼容性问题的一个示例:
Foo
对象序列化为文件。Foo
保存到文件中。Foo
发布程序的2.0版。如果版本2.0 Foo
具有版本1.0 Foo
没有的其他属性,这可能会很麻烦。您必须明确不支持此方案,或者在序列化方面有一些版本控制故事。 .NET可以为您做一些这样的事情。在这种情况下,您可能还会遇到相反的问题:用户可能会尝试使用您的程序版本1.0打开版本2.0 Foo
文件。
我自己没有使用过这些技术,但.NET 2.0及更高版本支持version tolerant serialization以支持向前和向后兼容:
- 容忍无关或意外的数据。这使该类型的较新版本能够将数据发送到旧版本。
- 缺少可选数据的容差。这使旧版本可以将数据发送到更新版本。
- 序列化回调。这样可以在缺少数据的情况下设置智能默认值。
答案 1 :(得分:2)
例如,当您想通过网络发送对象或将它们存储到文件中时。
假设您正在为视频游戏创建Savegame格式。然后,您可以将类Player
和每个Enemy
序列化。这样就可以很容易地将当前对象的状态保存到文件中。
另一方面,在为游戏编写多人游戏实施时,您可以将Player
序列化的网络发送给其他客户端,然后客户可以处理这些数据。
答案 2 :(得分:2)
在非面向对象的语言中,人们通常会将数据以字节模式存储在内存中,这些数据在没有引用任何其他内容的情况下“有意义”。例如,图形编辑器中的一堆形状可能只是连续存储所有点。在这样的程序中,简单地将所有数组的内容存储到磁盘可能会产生一个文件,当读回这些数组时会产生原始数据。
在面向对象语言中,许多对象存储为对其他对象的引用。仅仅存储内存数据结构的内容将没有用,因为对对象#24601的引用将不会说明该对象代表什么。虽然面向对象的系统可能能够很好地搞清楚内存数据“意味着什么”并尝试将其自动转换为合理的格式,但它无法识别对象引用之间的所有区别到同一个对象,以及那些指向恰好匹配的对象的对象。因此,在将对象转换为原始比特流时,通常需要帮助系统。
答案 3 :(得分:1)
不是类,但可以将特定对象序列化以存储在某个持久存储中,或者将对象传递给另一个应用程序/通过网络。
答案 4 :(得分:1)
例如,当您想要将对象发送到某个URL时,您可能决定以xml格式发送它。从内存中对象转换为(在本例中)xml的过程称为序列化。从xml转换为内存中称为反序列化。