首先了解下定义:
序列化是将对象转换为容易传输的格式的过程,一般情况下转化打流文件,放入内存或者IO文件中,
反序列化根据流重新构造对象。
为什么序列化,我从网上搜集的理由简言之:
为什么要序列化一个对象,大概出于两个目的。
第一保存对象以便以后再处理,这是出于对象持久化(persist)的要求。这种情况一般需要把对象保存到可以长久保存的介质上,比如磁盘。保存在磁盘上的数据是一系列连续的字节组成的,所以就需要把对象转换成一个连续的字节串以便把对象写入到磁盘。把一个对象当时的完整状态转换成连续的字节串的过程就是对象的序列化(serialize)过程。反过来把表示一个对象的连续的字节串复原成原来的那个对象的过程就是反序列化(deserialize)过程。
第二,自从有了分布式处理技术后,就出现了需要从一个应用传送一个对象到另一个应用的需求。不同的应用大多数情况是不在同一个机器上的,对象需要在网络上进行传输。跟写入到磁盘类似,网络传输数据也可以看做是传输一个连续的字节串。这种需求同样需要把对象先序列化成连续的字节串,经过网络传输到,到达目标应用,再经过反序列化恢复为对象。
还有不序列化信息也可以传输,但是跨平台很繁琐,安全性也无法保障。如果序列化以后通过特定的协议传输数据就不一样了
简单来说序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化,流的概念这里不用多说(就是I/O),我们可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间(注:要想将对象传输于网络必须进行流化)!在对对象流进行读写操作时会引发一些问题,而序列化机制正是用来解决这些问题的!
序列化的实现
将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个 ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。
.NET自带的有两种序列化对象的方式,Xml和binary的,XML 序列化不转换方法、索引器、私有字段或只读属性(只读集合除外)。要序列化对象的所有字段和属性(公共的和私有的),请使用 BinaryFormatter,而不要使用 XML 序列化。
序列化实例1:
建立一个应用程序
建立一个类ObjectStore
using System;
using System.Collections.Generic;
using System.Linq; using System.Text;
namespace ObjectStore
{
[Serializable]//指示一个类可以序列化。无法继承此类。
public class Product
{
public long Id;
public string Name;
public double Price;
[NonSerialized]//指示可序列化类的某个字段不应被序列化。无法继承此类。
string Notes;
public Product(long id, string name, double price, string notes)
{
Id = id;
Name = name;
Price = price;
Notes = notes;
}
public override string ToString()
{
return string.Format("{0}: {1} (${2:F2}) {3}", Id, Name, Price, Notes);
}
}
}
二进制的C#序列化的方式:
List<Product> products = new List<Product>();
products.Add(new Product(1, "Spiky Pung", 1000.0, "Good stuff."));
products.Add(new Product(2, "Gloop Galloop Soup", 25.0, "Tasty."));
products.Add(new Product(4, "Hat Sauce", 12.0, "One for the kids."));
// Get serializer.
IFormatter serializer = new BinaryFormatter();// IFormatter:提供将序列化对象格式化的功能。
// Serialize products.
FileStream saveFile =new FileStream("Products.bin", FileMode.Create,FileAccess.Write);
serializer.Serialize(saveFile, products);// 将对象或具有给定根的对象图形序列化为所提供的流。
saveFile.Close();
理论支持:
需要序列化该对象,必须在给该类加上Serializable的属性,然后创建一个序列化写入的流:FileStream fileStream = new FileStream("temp.dat", FileMode.Create);然后创建二进制格式器:BinaryFormatter b=new BinaryFormatter();然后是序列化:b.Serialize(fileStream,c);,然后关闭保存流。
// Deserialize products.//凡序列化
FileStream loadFile =new FileStream("Products.bin", FileMode.Open, FileAccess.Read);
List<Product> savedProducts = serializer.Deserialize(loadFile) as List<Product>;//反序列化所提供流中的数据并重新组成对象图形。
loadFile.Close();
二进制序列化
3.1.将准备好的对象序列化到准备好的流对象中
使用BinaryFormatter对象的Serialize方法进行序列化:
BinaryFormatter.Serialize (Stream, Object)
这里有几点需要特别强调的:
BinaryFormatter把对象转换成二进制的序列数据,其中总不免会有字符存在,比如字符串类型的字段,对字符同样在序列化过程默认采用UTF-8编码,而且好像无法改变这个编码。
/// <summary>
/// 将准备好的对象序列化到准备好的流对象中
/// </summary>
static void Serialize()
{
//准备序列化器BinaryFormatter
BinaryFormatter formatter = new BinaryFormatter();
//序列化mybook对象,序列化到myMemoryStream流对象
formatter.Serialize(myMemoryStream, mybook);
#region 将流中的数据转换为字符串
byte[] resultByte = myMemoryStream.GetBuffer();
string resultStr = Encoding.UTF8.GetString(resultByte);
#endregion
}
二进制反序列化
static void Deserialize()
{
myMemoryStream.Position = 0;
BinaryFormatter formatter = new BinaryFormatter();
mybook = (book)formatter.Deserialize(myMemoryStream);
}