Serialization即序列化,序列化是可被定义为将对象的状态存储到存储媒介中的过程。在此过程中,对象的公共字段和私有字段以及类的名称(包括包含该类的程序集)都被转换为字节流,然后写入数据流。在以后反序列化该对象时,创建原始对象的精确复本。
Remoting和Web Service就是序列化的典型的应用,通过序列化将一个对象从一个应用程序域,发送到另一个应用程序域。
序列化类默认的情况下是要求他的所有的成员都是要可序列化的(除事件、委托、显式定义不可序列化),对于不想被序列化的成员要声明不可序列化把它加上 [NonSerialized]属性告诉.NET这个类不要被序列化,这样在序列化的时候就不会保存对象的状态。
下面就将常用的几种序列化方式一一实现出来给大家看一下!
首先需要新建一个被实例化的类:Person.cs
namespace SerializationTest
{
[Serializable]//此属性标记为该类可以实例化
[XmlRoot("Hello")]//标记为XML文档的根节点名字
public class Person<T>
{
[XmlAttribute("Name")]/标记为XML文档属性名
public string Name
{
get;
set;
}
[XmlAttribute("Sex")]
public string Sex
{
get;
set;
}
[XmlAttribute("Age")]
public int Age
{
get;
set;
}
[NonSerialized]//此属性标记为不可序列化
Work w;
public Work W
{
get
{
return w;
}
set
{
w = value;
}
}
}
public class Work
{
[XmlAttribute("WorkName")]
public string WorkName
{
get;
set;
}
}
下面开始介绍常使用的几种序列化的方法
一、BinaryFormatter
在使用之前需要先引入命名空间:
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Binary;
具体的实现方法如下:
//BinaryFormatter方式序列化
private static void Serializable(Person<Work> p)
{
IFormatter formatter = new BinaryFormatter();
//创建文件流
Stream stream = new FileStream(@"D:\Persons.bin", FileMode.Create, FileAccess.Write, FileShare.None);
using (stream)
{
formatter.Serialize(stream, p);
}
Console.WriteLine("序列化完成!");
Console.ReadKey();
Console.WriteLine("按任意键继续反序列化!");
Console.ReadKey();
}
//BinaryFormatter方式反序列化
private static void Deserializable()
{
Person<Work> p;
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream(@"D:\Persons.bin", FileMode.Open, FileAccess.Read, FileShare.None);
using (stream)
{
p = (Person<Work>)formatter.Deserialize(stream);
}
if (p.W == null)
{
Console.WriteLine(p.Name + "::" + p.Sex + "::" + p.Age );
}
else
{
Console.WriteLine("Person类的Work属性未被实例化!");
}
}
//BinaryFormatter方式序列化
private static void Serializable(Person<Work> p)
{
IFormatter formatter = new BinaryFormatter();
//创建文件流
Stream stream = new FileStream(@"D:\Persons.bin", FileMode.Create, FileAccess.Write, FileShare.None);
using (stream)
{
formatter.Serialize(stream, p);
}
Console.WriteLine("序列化完成!");
Console.ReadKey();
Console.WriteLine("按任意键继续反序列化!");
Console.ReadKey();
}
//BinaryFormatter方式反序列化
private static void Deserializable()
{
Person<Work> p;
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream(@"D:\Persons.bin", FileMode.Open, FileAccess.Read, FileShare.None);
using (stream)
{
p = (Person<Work>)formatter.Deserialize(stream);
}
if (p.W == null)
{
Console.WriteLine(p.Name + "::" + p.Sex + "::" + p.Age );
}
else
{
Console.WriteLine("Person类的Work属性未被实例化!");
}
}
在Main函数中调用如下
static void Main(string[] args)
{
Person<Work> p = new Person<Work>()
{
Name = "Olive",
Sex = "female",
Age = 22,
W = new Work()
{
WorkName = "Student"
}
};
Serializable(p); //BinaryFormatter序列化,将对象以二进制流的方式写入本地文件
Deserializable(); //BinaryFormatter反序列化 ,从本地文件读取二进制流,反序列化为对象
}
执行完之后效果如下:
1、在D盘产生一个Person.bin文件,保存的就是Person对象的属性,
2、反序列化后,可以重新得到对象
二、SoapFormatter
要序列化成SOAP就要先用引用System.Runtime.Serialization.Formatters.Soap命名空间中的SoapFormatter类。
SoapFormatter是一个Soap的格式器
具体的代码如下:(还是引用开始的Person类)
//SoapFormatter方式序列化
private static void SoapSerializable(Person p)
{
IFormatter formatter = new SoapFormatter();
Stream stream=new FileStream(@"D:\Person.xml",FileMode.Create,FileAccess.Write,FileShare.None);
using(stream)
{
formatter.Serialize(stream,p);
}
Console.WriteLine("SoapSerializable序列化完毕!");
}
//SoapFormatter反序列化
private static void DesoapSerializable()
{
Person p;
IFormatter formatter = new SoapFormatter();
Stream stream = new FileStream(@"D:\Person.xml", FileMode.Open, FileAccess.Read, FileShare.None);
using (stream)
{
p = (Person )formatter.Deserialize(stream);
}
Console.WriteLine(p.Name + "::" + p.Sex + "::" + p.Age);
Console.WriteLine("SoapSerializable反序列化完毕!");
}
主函数
static void Main(string[] args)
{
Person p = new Person()
{
Name = "Olive",
Sex = "female",
Age = 22,
W = new Work()
{
WorkName = "Student"
}
};
SoapSerializable(p); //SoapFormatter序列化,(但是不支持泛型的序列化 )将对象序列化为xml格式的字符串,存入本地.xml文件
DesoapSerializable(); //SoapFormatter反序列化
}
执行完之后效果如下:
1、在D盘产生一个Person.XML文件,保存的就是Person对象的属性,
2、反序列化后,可以重新得到对象
三、XmlSerializer
首先需要引入命名空间:System.Xml.Serialization
主要代码如下:
//XMLSerializable序列化
private static void XMLSerializable(Person<Work> p)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Person<Work>));
Stream stream = new FileStream(@"D:\XMLPerson.xml", FileMode.Create, FileAccess.Write, FileShare.None);
using (stream)
{
xmlSerializer.Serialize(stream, p);
}
Console.WriteLine("XMLSerializable序列化完毕!");
Console.WriteLine("按任意键继续反序列化!");
Console.ReadKey();
}
//XMLSerializable反序列化
private static void DeXMLSerializable()
{
Person<Work> p;
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Person<Work>));
Stream stream = new FileStream(@"D:\XMLPerson.xml", FileMode.Open, FileAccess.Read, FileShare.None);
using (stream)
{
p = (Person<Work>)xmlSerializer.Deserialize(stream);
}
if (p != null)
{
Console.WriteLine(p.Name + "::" + p.Sex + "::" + p.Age);
Console.WriteLine("XMLSerializable反序列化成功!");
}
else
Console.WriteLine("XMLSerializable反序列化失败!");
}
主函数调用如下:
static void Main(string[] args)
{
Person<Work> p = new Person<Work>()
{
Name = "Olive",
Sex = "female",
Age = 22,
W = new Work()
{
WorkName = "Student"
}
};
XMLSerializable(p); //XMLSerializable序列化 ,将对象序列化为XML格式的字符串
DeXMLSerializable(); // XMLSerializable序列化
}
执行后效果如下:
1、在D盘产生一个XMLPerson.XML文件,保存的就是Person对象的属性,
2、反序列化后,可以重新得到对象
这里的跟节点之所是Hello而不是Person是因为在Person类中,将Person的类的跟节点标记为
[XmlRoot("Hello")]
public class Person<T>{}
同时Work的节点名为W也是这个缘故
[XmlAttribute("WorkName")]
public string WorkName
{
get;
set;
}
四、DataContractJsonSerializer(将对象序列化为Json格式的字符串)
在使用前需要添加引用:System.ServiceModel.Web 和 System.Runtime.Serialization,
然后使用
using System.Runtime.Serialization.Json;ITPUB个人空间3htH4O+A.sQ!n
using System.Runtime.Serialization;
具体代码如下:
//SerializableJson 将对象序列化为Json格式字符串
private static string SerializableJson(Person<Work> p)
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Person<Work>));
using (MemoryStream memory = new MemoryStream())
{
serializer.WriteObject(memory, p);
result = UTF8Encoding.Default.GetString(memory.ToArray());
Console.WriteLine(result);
}
Console.WriteLine("SerializableJson序列化完毕!");
return result;
}
//SerializableJson 将Json格式的字符串序列化为对象
private static void DeSerializableJson(string jsonString)
{
Person<Work> p;
var serializer = new DataContractJsonSerializer(typeof(Person<Work>));
using (MemoryStream memory = new MemoryStream(UTF8Encoding.Default.GetBytes(jsonString)))
{
p = (Person<Work>)serializer.ReadObject(memory);
}
Console.WriteLine(p.Name + "::" + p.Sex + "::" + p.Age);
Console.WriteLine("Json序列化完毕了!");
Console.WriteLine("按任意键继续");
Console.ReadKey();
}
主函数调用
static void Main(string[] args)
{
Person<Work> p = new Person<Work>()
{
Name = "Olive",
Sex = "female",
Age = 22,
W = new Work()
{
WorkName = "Student"
}
};
结果如下:
五、DataContactSerializer(可以将对象序列化为Json格式的字符串和XML格式的字符串,为Json格式时,需要在将要序列化的类属性上添加[DataMember]特性,
为XML格式时,需要在将要序列化的类属性上添加[XmlAttribute("属性名")]特性,这样就会根据所添加的特性的不同而生成不同格式的字符串
首先需要添加引用:
using System.ServiceModel;
具体代码如下:(生成JSON格式的字符串)
private static string SerializerDataContract(Person<Work> p)
{
DataContractSerializer dataSerializer = new DataContractSerializer(typeof(Person<Work>));
using (MemoryStream memory = new MemoryStream())
{
dataSerializer.WriteObject(memory, p);
result = UTF8Encoding.Default.GetString(memory.ToArray());
Console.WriteLine(result);
Console.WriteLine("DataContractSerializer序列化完毕!");
}
return result;
}
private static void DeSerializerDataContract(string result)
{
Person<Work> p;
DataContractSerializer dataSerializer = new DataContractSerializer(typeof(Person<Work>));
using (MemoryStream memory = new MemoryStream(UTF8Encoding.Default.GetBytes(result)))
{
p = (Person<Work>)dataSerializer.ReadObject(memory);
Console.WriteLine(p.Name + ":::" + p.Sex + ":::" + p.Age);
}
}
主函数调用:
static void Main(string[] args)
{
Person<Work> p = new Person<Work>()
{
Name = "Olive",
Sex = "female",
Age = 22,
W = new Work()
{
WorkName = "Student"
}
};
SerializerDataContract(p);
DeSerializerDataContract(result);
}
执行结果如下:
六、将对象序列化为字符串、或者字节数组
先要引用命名空间
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Soap;
using System.Runtime.Serialization.Formatters.Binary;
using system.Runtime.
主要代码:
//SerializableString将对象序列化为字符串
private static string SerializableString(Person<Work> p)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Person<Work>));
using (MemoryStream memoryStream = new MemoryStream())
{
xmlSerializer.Serialize(memoryStream, p);
result = UTF8Encoding.Default.GetString(memoryStream.ToArray());
Console.WriteLine(result);
return result;
}
}
//将字符串反序列化为对象
public static void DeSerializableString(string result, Person<Work> p)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Person<Work>));
using (StringReader stringReader = new StringReader(result))
{
p = (Person<Work>)xmlSerializer.Deserialize(stringReader);
}
Console.WriteLine(p.Name + "::" + p.Sex + "::" + p.Age);
Console.WriteLine("反序列化完毕!");
}
private static byte[] buffer;
//将对象序列化为字节数组
private static byte[] SerializableObjcet(Person<Work> p)
{
IFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
buffer = new byte[stream.Length];
using (stream)
{
formatter.Serialize(stream, p);
stream.Position = 0;
stream.Read(buffer, 0, buffer.Length);
}
Console.WriteLine("Serialization字节数组转换成功!");
return buffer;
}
//将字节数组转化为对象
private static void DeSerializableObject(byte[] bytes)
{
if (buffer != null)
{
Person<Work> p;
IFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream(bytes);
using (stream)
{
p = (Person<Work>)formatter.Deserialize(stream);
}
Console.WriteLine(p.Name + "::" + p.Sex + "::" + p.Age);
Console.WriteLine("字节数组反序列化成功!");
}
else
{
Console.WriteLine("字节数组为空!");
}
}
执行结果如下:
至此,基本上已经介绍了常用的序列化的方法,希望能对大家有一定的帮助,同时也算是我自己的学习总结吧!