2010-10-21 115 views
6

序列化到底在哪里?我对“网了解serializtion和我来知道什么是序列化?

它是一个接口,如果在一个类实现,意味着它可以自动进行序列化,并通过不同的串行解串。

给我一个很好的理由为什么和什么时候需要序列化一个类?假设一旦它被序列化,究竟发生了什么?

回答

25

无论何时需要持续或传输对象超出其存在范围时,都需要序列化。

持久性是能够将某个对象保存到某处并稍后以相同的状态加载它。例如:

  • 您可能需要将对象实例存储在磁盘上作为文件的一部分。
  • 您可能需要将对象作为blob(二进制大对象)存储在数据库中。

传输是将对象以外的对象发送到某个接收者的能力。例如:

  • 您可能需要将对象的实例传输到远程计算机。
  • 您可能需要将实例传输到另一个AppDomain或进程在同一台计算机上。

对于其中的每一个,都必须有一些可以存储,通信,然后用来重构原始对象的串行位表示。将对象转换为这一系列位的过程称为“序列化”,而将一系列位转换为原始对象的过程称为“反序列化”。

以序列化形式表示对象的实际表示形式可能因您的目标不同而有所不同。例如,在C#中,您同时具有XML序列化(通过XmlSerializer类)和二进制序列化(通过使用BinaryFormatter类)。根据您的需要,您甚至可以编写自己的自定义序列化程序来执行额外的工作,例如压缩或加密。如果你需要一种语言和平台无关的序列化格式,你可以试试谷歌的Protocol Buffers,它现在有support for .NET(我没有用过)。

上面提到的XML表示方式适用于以标准格式存储对象,但根据您的需要它可以是冗长和缓慢的。二进制表示可以节省空间,但不像XML那样可以跨语言和运行时移植。重要的一点是串行器和解串器必须相互理解。当您开始引入向后和向前兼容性和版本控制时,这可能是一个问题。

的潜在系列化兼容性问题的一个例子:

  • 你发布你的程序,它是能够序列化一些Foo对象文件的版本1.0。
  • 用户执行一些操作将其Foo保存到文件中。
  • 您使用更新的Foo发布程序的2.0版。
  • 用户试图用您的2.0版程序打开1.0版文件。

如果2.0 Foo版本具有版本1.0 Foo没有的附加属性,则这可能很麻烦。你必须明确不支持这种情况,或者在你的序列化中有一些版本控制的故事。 .NET可以为你做一些这样的事情。在这种情况下,您可能也会遇到相反的问题:用户可能会尝试使用程序的版本1.0打开2.0版本的Foo文件。

我还没有使用这些技术自己,但.NET 2.0和更高版本具有支持version tolerant serialization同时支持向前和向后兼容性:

  • 无关的或意外的数据的宽容。这使得该类型的更新版本可以将数据发送到旧版本。
  • 缺少可选数据的容差。这使旧版本可以将数据发送到更新的版本。
  • 序列化回调。这可以在数据丢失的情况下实现智能默认值设置。
+0

你可以给我一个场景或例子,其中的对象需要持续超出其存在的范围? – FosterZ 2010-10-21 05:17:14

+0

哦,很好,谢谢 – FosterZ 2010-10-21 05:19:09

+0

thanx的附加信息'谷歌协议缓冲区'和'版本容忍序列化'。 – FosterZ 2010-10-21 06:26:15

1

不是类,但具体的对象可能被序列在一些持久性存储器以存储或对象/传递给另一个应用程序通过网络。

2

例如,当您想通过网络发送对象或将它们存储到文件中时。

可以说你正在为一个视频游戏创建一个Savegame格式。然后您可以使课程Player和每个Enemy可序列化。这样可以很容易地将当前对象的状态保存到文件中。另一方面,在为游戏编写多人游戏实现时,您可以将Player通过网络序列化到其他客户端,然后可以处理这些数据。

+0

你的例子很好..thnx – FosterZ 2010-10-21 05:26:43

1

例如,当你想发送一个对象到某个url时,你可能决定以xml格式发送它。从内存中的对象转换(在本例中)xml的过程称为序列化。从xml转换到内存被称为反序列化。

2

在非面向对象的语言中,通常会将数据以字节模式存储在内存中,这些字节在没有引用任何其他内容的情况下“有意义”。例如,图形编辑器中的一组形状可能只是将所有点连续存储。在这样的程序中,简单地将所有数组的内容存储到磁盘可能会产生一个文件,当读回这些数组时,将产生原始数据。

在面向对象的语言中,许多对象存储为对其他对象的引用。仅仅存储内存数据结构的内容将不会有用,因为对对象#24601的引用不会说任何关于该对象所代表的内容。虽然面向对象的系统可以很好地找出内存中的数据“意味着什么”并尝试将其自动转换为合理的格式,但它无法识别对象引用之间的所有区别,到同一个对象,以及那些指向碰巧匹配的对象。因此在将对象转换为原始位流时常常需要帮助系统。