序列化就是是将东西转换为容易传输的格局的过程,一般情况下转化打流文件,放入内存或者IO文件 中。例如,可以序列化一个东西,然后使用 HTTP 通过 Internet 在客户端和处事器之间传输该东西,或者和其它应用措施共享使用。反之,反序列化按照流从头结构东西。
一、几种序列化技术
1)二进制序列化连结类型保真度,这对付在应用措施的差别挪用之间保存东西的状态很有用。例如,,通过将东西序列化到剪贴板,可在差此外应用措施之间共享东西。您可以将东西序列化到流、磁盘、内存和网络等等。长途措置惩罚惩罚使用序列化“通过值”在计算机或应用措施域之间通报东西。
2)XML 序列化仅序列化大众属性和字段,且不连结类型保真度。当您要供给或使用数据而不限制使用该数据的应用措施时,这一点是很有用的。由于 XML 是一个开放式标准,因此,对付通过 Web 共享数据而言,这是一个很好的选择。SOAP 同样是一个开放式标准,这使它也成为一个颇具吸引力的选择。
3)使用供给的数据协定,将类型实例序列化和反序列化为 XML 流或文档(或者JSON格局)。常应用于WCF通信。
二、序列化分类
1、根基序列化
要使一个类可序列化,最简单的要领是使用 Serializable 属性对它进行符号,如下所示
代码如下:
[Serializable]
public class MyObject
{
public int n1 = 0;
public int n2 = 0;
public String str = null;
}
将上面的类的一个实例序列化为一个文件
代码如下:
MyObject obj = new MyObject();
obj.n1 = 1;
obj.n2 = 24;
obj.str = “一些字符串”;
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream(“MyFile.bin”, FileMode.Create,
FileAccess.Write, FileShare.None);
formatter.Serialize(stream, obj);
stream.Close();
上面实例的反序列化
代码如下:
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream(“MyFile。bin”, FileMode.Open,
FileAccess.Read, FileShare.Read);
MyObject obj = (MyObject) formatter.Deserialize(fromStream);
stream.Close();
如果要求具有可移植性,请使用 SoapFormatter。所要做的变动只是将以上代码中的格局化措施换成 SoapFormatter,而 Serialize 和 Deserialize 挪用不乱。
需要注意的是,无法担任 Serializable 属性。如果从 MyObject 派生出一个新的类,则这个新的类也必需使用该属性进行符号,否则将无法序列化。例如,如果试图序列化以下类实例,将会显示一个 SerializationException,说明 MyStuff 类型未符号为可序列化。
2、选择性序列化
类凡是包罗不应被序列化的字段。例如,假设某个类用一个成员变量来存储线程 ID。当此类被反序列化时,序列化此类时所存储的 ID 对应的线程可能不再运行,所以对这个值进行序列化没有意义。可以通过使用 NonSerialized 属性符号成员变量来防备它们被序列化,如下所示:
代码如下:
[Serializable]
public class MyObject
{
public int n1;
[NonSerialized]
public int n2;
public String str;
}
3、自界说序列化
可以通过在东西上实现 ISerializable 接口来自界说序列化过程。这一成果在反序列化后成员变量的值掉效时尤其有用,但是需要为变量供给值以重建东西的完整状态。要实现 ISerializable,需要实现 GetObjectData 要领以及一个特殊的结构函数,在反序列化东西时要用到此结构函数。以下代码示例说明了如安在前一部分中提到的 MyObject 类上实现 ISerializable。
代码如下:
[Serializable]
public class MyObject : ISerializable
{
public int n1;
public int n2;
public String str;
public MyObject()
{
}
protected MyObject(SerializationInfo info, StreamingContext context)
{
n1 = info.GetInt32(“i”);
n2 = info.GetInt32(“j”);
str = info.GetString(“k”);
}
public virtual void GetObjectData(SerializationInfo info,
StreamingContext context)
{
info.AddValue(“i”, n1);
info.AddValue(“j”, n2);
info.AddValue(“k”, str);
}
}
在序列化过程中挪用 GetObjectData 时,需要填充要领挪用*给的 SerializationInfo 东西。只需按名称/值对的形式添加将要序列化的变量。其名称可以是任何文本。只要已序列化的数据足以在反序列化过程中还原东西,便可以*选择添加至 SerializationInfo 的成员变量。如果基东西实现了 ISerializable,则派生类应挪用其基东西的 GetObjectData 要领。