序列化
序列化是将对象状态转换为可保持(保存)或传输的形式的过程。序列化的补集是反序列化,后者将流转换为对象。这两个过程一起保证数据易于存储和传输。
我们注意一下:对象状态指的是保存的字段。字段对序列化有影响而方法没有影响。序列化和反序列化都必须依靠本类。我们可以说序列化是把字段中的数据保存在一个文件下,而反序列化是取值的过程。如果没有继承的序列化我们可以说序列化时通过new出的对象来写入数据的,反序列化时是通过文件来获取数据的。我们不能对属性进行序列化。
序列化是将对象状态转换为可保持(保存)或传输的形式的过程。序列化的补集是反序列化,后者将流转换为对象。这两个过程一起保证数据易于存储和传输。
我们注意一下:对象状态指的是保存的字段。字段对序列化有影响而方法没有影响。序列化和反序列化都必须依靠本类。我们可以说序列化是把字段中的数据保存在一个文件下,而反序列化是取值的过程。如果没有继承的序列化我们可以说序列化时通过new出的对象来写入数据的,反序列化时是通过文件来获取数据的。我们不能对属性进行序列化。
.NET Framework 提供了两个序列化技术:
二进制序列化保持类型保真,这对于多次调用应用程序时保持对象状态非常有用。例如,通过将对象序列化到剪贴板,可在不同的应用程序之间共享对象。您可以将对象序列化到流、磁盘、内存和网络等。远程处理使用序列化,“按值”在计算机或应用程序域之间传递对象。
XML 序列化只序列化公共属性和字段,并且不保持类型保真。当您希望提供或使用数据而不限制使用该数据的应用程序时,这一点非常有用。由于 XML 是开放式的标准,因此它对于通过 Web 共享数据来说是一个理想选择。SOAP 同样是开放式的标准,这使它也成为一个理想选择。
二进制序列化保持类型保真,这对于多次调用应用程序时保持对象状态非常有用。例如,通过将对象序列化到剪贴板,可在不同的应用程序之间共享对象。您可以将对象序列化到流、磁盘、内存和网络等。远程处理使用序列化,“按值”在计算机或应用程序域之间传递对象。
XML 序列化只序列化公共属性和字段,并且不保持类型保真。当您希望提供或使用数据而不限制使用该数据的应用程序时,这一点非常有用。由于 XML 是开放式的标准,因此它对于通过 Web 共享数据来说是一个理想选择。SOAP 同样是开放式的标准,这使它也成为一个理想选择。
可以将序列化定义为一个将对象状态存储到存储介质的过程。在这个过程中,对象的公共字段和私有字段以及类(包括含有该类的程序集)的名称,将转换成字节流,而字节流接着将写入数据流。随后对该对象进行反序列化时,将创建原始对象的准确克隆。
(1)二进制序列化
二进制序列化需要的命名空间
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
序列化类
[Serializable]
public class Person
{
public int age;
public bool Sex
{ get; set; }
}
序列化
Person XiaoHong = new Person();
XiaoHong.age = 18;
XiaoHong.Sex = false;
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("F:/MyFile.bin", FileMode.Create, FileAccess.Write, FileShare.None);
formatter.Serialize(stream, XiaoHong);
stream.Close();
(1)二进制序列化
二进制序列化需要的命名空间
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
序列化类
[Serializable]
public class Person
{
public int age;
public bool Sex
{ get; set; }
}
序列化
Person XiaoHong = new Person();
XiaoHong.age = 18;
XiaoHong.Sex = false;
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("F:/MyFile.bin", FileMode.Create, FileAccess.Write, FileShare.None);
formatter.Serialize(stream, XiaoHong);
stream.Close();
反序列化
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("F:/xh.bin", FileMode.Open, FileAccess.Read, FileShare.Read);
Person XiaoHong = (Person)formatter.Deserialize(stream);
stream.Close();
MessageBox.Show(string .Format ("年龄:{0} 性别:{1}",XiaoHong .age ,XiaoHong .Sex ));
如果没有继承的序列化我们可以说序列化时通过new出的对象来写入数据的,反序列化时是通过文件来获取数据的。
(2)选择序列化
[Serializable]
public class Person
{
[NonSerialized]
public int age;
public bool Sex
{ get; set; }
}
选择序列化时我们只能对字段加[NonSerialized]不能对属性加序列化。
(3)自定义序列化
自定义序列化是控制类型的序列化和反序列化的过程。通过控制序列化,可以确保序列化兼容性。换而言之,在不中断类型核心功能的情况下,可在类型的不同版本之间序列化和反序列化。
例子:
父类没有序列化而子类想要序列化时需要子类继承ISerializable 的接口通过构造函数去实现反序列化时数据的读取。
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("F:/xh.bin", FileMode.Open, FileAccess.Read, FileShare.Read);
Person XiaoHong = (Person)formatter.Deserialize(stream);
stream.Close();
MessageBox.Show(string .Format ("年龄:{0} 性别:{1}",XiaoHong .age ,XiaoHong .Sex ));
如果没有继承的序列化我们可以说序列化时通过new出的对象来写入数据的,反序列化时是通过文件来获取数据的。
(2)选择序列化
[Serializable]
public class Person
{
[NonSerialized]
public int age;
public bool Sex
{ get; set; }
}
选择序列化时我们只能对字段加[NonSerialized]不能对属性加序列化。
(3)自定义序列化
自定义序列化是控制类型的序列化和反序列化的过程。通过控制序列化,可以确保序列化兼容性。换而言之,在不中断类型核心功能的情况下,可在类型的不同版本之间序列化和反序列化。
例子:
父类没有序列化而子类想要序列化时需要子类继承ISerializable 的接口通过构造函数去实现反序列化时数据的读取。
public class Person
{
public bool sex;
}
[Serializable]
public class Chinese : Person,ISerializable
{
public string complexion;
public Chinese()
{ }
public Chinese(SerializationInfo info, StreamingContext context)
{
sex = info.GetBoolean("sex");
complexion = info.GetString("complexion");
}
[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("sex", sex);
info.AddValue("complexion", complexion);
}
}
{
public bool sex;
}
[Serializable]
public class Chinese : Person,ISerializable
{
public string complexion;
public Chinese()
{ }
public Chinese(SerializationInfo info, StreamingContext context)
{
sex = info.GetBoolean("sex");
complexion = info.GetString("complexion");
}
[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("sex", sex);
info.AddValue("complexion", complexion);
}
}
private void button1_Click(object sender, EventArgs e)//序列化
{
Chinese XiaoHong = new Chinese();
XiaoHong.sex = false;
XiaoHong.complexion = "Yellow“;
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("F:/xh.bin", FileMode.Create, FileAccess.Write, FileShare.None);
formatter.Serialize(stream, XiaoHong);
stream.Close();
}
private void button2_Click(object sender, EventArgs e)//反序列化
{
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("F:/xh.bin", FileMode.Open, FileAccess.Read, FileShare.Read);
Chinese XiaoHong = (Chinese)formatter.Deserialize(stream);
stream.Close();
MessageBox.Show(string.Format(“性别:{0},肤色:{1}”, XiaoHong.sex, XiaoHong.complexion));
}
我们注意:自定义的序列化的数据是通过GetObjectData()方法获得的。而反序列化是通过 public Chinese(SerializationInfo info, StreamingContext context){}去取值的。
如果使用 Serializable 属性对某个类进行标记,且该类在类级别或对其构造函数具有声明性或强制性安全要求,则不应对该类执行默认的序列化。相反,这样的类应该始终实现 ISerializable 接口。
实现 ISerializable 涉及到实现 GetObjectData 方法以及反序列化对象时所用的特殊构造函数。
强调何时将 ISerializable 添加至必须同时实现 GetObjectData 和特殊构造函数的某个类,这一点很重要。如果缺少 GetObjectData,编译器会向您发出警告。但是,鉴于无法强制实现构造函数,如果不存在该构造函数,则不会发出任何警告,但此时如果尝试对某个类进行反序列化,将会引发异常。
{
Chinese XiaoHong = new Chinese();
XiaoHong.sex = false;
XiaoHong.complexion = "Yellow“;
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("F:/xh.bin", FileMode.Create, FileAccess.Write, FileShare.None);
formatter.Serialize(stream, XiaoHong);
stream.Close();
}
private void button2_Click(object sender, EventArgs e)//反序列化
{
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("F:/xh.bin", FileMode.Open, FileAccess.Read, FileShare.Read);
Chinese XiaoHong = (Chinese)formatter.Deserialize(stream);
stream.Close();
MessageBox.Show(string.Format(“性别:{0},肤色:{1}”, XiaoHong.sex, XiaoHong.complexion));
}
我们注意:自定义的序列化的数据是通过GetObjectData()方法获得的。而反序列化是通过 public Chinese(SerializationInfo info, StreamingContext context){}去取值的。
如果使用 Serializable 属性对某个类进行标记,且该类在类级别或对其构造函数具有声明性或强制性安全要求,则不应对该类执行默认的序列化。相反,这样的类应该始终实现 ISerializable 接口。
实现 ISerializable 涉及到实现 GetObjectData 方法以及反序列化对象时所用的特殊构造函数。
强调何时将 ISerializable 添加至必须同时实现 GetObjectData 和特殊构造函数的某个类,这一点很重要。如果缺少 GetObjectData,编译器会向您发出警告。但是,鉴于无法强制实现构造函数,如果不存在该构造函数,则不会发出任何警告,但此时如果尝试对某个类进行反序列化,将会引发异常。
[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]——序列化可以允许其他代码查看或修改用其他方式无法访问的对象实例数据,本属性就是安全访问权限的设置。
SerializationInfo——存储将对象序列化或反序列化所需的全部数据。
StreamingContext——描述给定的序列化流的源和目标,并提供一个由调用方定义的附加上下文。
(4)XML序列化
序列化
using System.Runtime.Serialization.Formatters.Soap;//注意我们需要添加引用去实现命名 //空间的添加
Person XiaoHong = new Person();
XiaoHong.age = 18;
XiaoHong.Sex = false;
IFormatter formatter = new SoapFormatter();
Stream stream = new FileStream("F:/MyFile.xml", FileMode.Create, FileAccess.Write, FileShare.None);
formatter.Serialize(stream, XiaoHong);
stream.Close();
SerializationInfo——存储将对象序列化或反序列化所需的全部数据。
StreamingContext——描述给定的序列化流的源和目标,并提供一个由调用方定义的附加上下文。
(4)XML序列化
序列化
using System.Runtime.Serialization.Formatters.Soap;//注意我们需要添加引用去实现命名 //空间的添加
Person XiaoHong = new Person();
XiaoHong.age = 18;
XiaoHong.Sex = false;
IFormatter formatter = new SoapFormatter();
Stream stream = new FileStream("F:/MyFile.xml", FileMode.Create, FileAccess.Write, FileShare.None);
formatter.Serialize(stream, XiaoHong);
stream.Close();
反序列化
IFormatter formatter = new SoapFormatter();
Stream stream = new FileStream("F:/MyFile.xml", FileMode.Open, FileAccess.Read, FileShare.Read);
Person XiaoHong = (Person)formatter.Deserialize(stream);
stream.Close();
MessageBox.Show(string .Format ("年龄:{0} 性别:{1}",XiaoHong .age ,XiaoHong .Sex ));
Stream stream = new FileStream("F:/MyFile.xml", FileMode.Open, FileAccess.Read, FileShare.Read);
Person XiaoHong = (Person)formatter.Deserialize(stream);
stream.Close();
MessageBox.Show(string .Format ("年龄:{0} 性别:{1}",XiaoHong .age ,XiaoHong .Sex ));
转载于:https://blog.51cto.com/zhjjzhjj/368621