一直感觉理解西方人传进来的名词特别扭,序列化与反序列化我更喜欢叫把他理解为:序列化-将对象转化为二进制流,反序列化-将二进制流转化为对象
二、为什么需要序列化、反序列化 (摘抄)
1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
我们经常需要将对象的字段值保存到磁盘中,并在以后检索此数据。尽管不使用序列化也能完成这项工作,但这种方法通常很繁琐而且容易出错,并且在需要跟踪对象的层次结构时,会变得越来越复杂。可以想象一下编写包含大量对象的大型业务应用程序的情形,程序员不得不为每一个对象编写代码,以便将字段和属性保存至磁盘以及从磁 盘还原这些字段和属性。序列化提供了轻松实现这个目标的快捷方法。公共语言运行时 (CLR) 管理对象在内存中的分布,.NET 框架则通过使用反射提供自动的序列化机制。对象序列化后,类的名称、程序集以及类实例的所有数据成员均被写入存储媒体中。对象通常用成员变量来存储对其他实例的引用。类序列化后,序列化引擎将跟踪所有已序列化的引用对象,以确保同一对象不被序列化多次。.NET 框架所提供的序列化体系结构可以自动正确处理对象图表和循环引用。对对象图表的唯一要求是,由正在进行序列化的对象所引用的所有对象都必须标记为 Serializable(请参阅基 本序列化)。否则,当序列化程序试图序列化未标记的对象时将会出现异常。当反序列化已序列化的类时,将重新创建该类,并自动还原所有数据成员的值。
2) 在网络上传送对象的字节序列。
对象仅在创建对象的应用程序域中有效。除非对象是从MarshalByRefObject派生得到或标记为 Serializable,否则,任何将对象作为参数传递或将其作为结果返回的尝试都将失败。如果对象标记为 Serializable,则该对象将被自动序列化,并从一个应用程序域传输至另一个应用程序域,然后进行反序列化,从而在第二个应用程序域中产生出该对象的一个精确副本。此过程通常称为按值封送。如果对象是从MarshalByRefObject派生得到,则从一个应用程序域传递至另一个应用程序域的是对象引用,而不是对象本身。也可以将从MarshalByRefObject派生得到的对象标记为Serializable。远程使用此对象时,负责进行序列化并已预先配置为SurrogateSelector的格式化程序将控制序列化过程,并用一个代理替换所有从MarshalByRefObject派生得到的对象。如果没有预先配置为SurrogateSelector,序列化体系结构将遵从下面的标准序列化规则。
三、怎么序列化(winform代码实例)
.net 提供了三种序列化机制XML Serializer,BinarySerializer,SOAP Serializer,下面用代码实例来做说明。
首先在在项目中添加一个类文件,代码为:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WindowsFormsApplication1
{
[Serializable]
public class Product
{
public long Id;
public string Name;
public double Price;
[NonSerialized]
string Notes;
public Product() {
}
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},{3},",Id,Name,Price,Notes);
}
}
}
建建一个Winform窗口,代码为:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
//序列化
private void button1_Click(object sender, EventArgs e)
{
List<Product> product = new List<Product>();
product.Add(new Product(1, "spiky pung", 1000.0, "Good stuff."));
product.Add(new Product(2, "Gloop Galloop Soup", 25.0, "Tasty."));
product.Add(new Product(4, "Hat Sauce", 12.0, "One for the kids."));
IFormatter formatter = new BinaryFormatter();
FileStream stream = new FileStream("object.bin", FileMode.Create, FileAccess.Write, FileShare.None);
formatter.Serialize(stream, product);
stream.Close();
}
//反序列化
private void button2_Click(object sender, EventArgs e)
{
List<Product> product = new List<Product>();
IFormatter formatter = new BinaryFormatter();
FileStream stream = new FileStream("object.bin", FileMode.Open, FileAccess.Read, FileShare.None);
List<Product> saveProduct = formatter.Deserialize(stream) as List<Product>;
foreach (Product pro in saveProduct) {
label1.Text += pro.ToString();
}
}
//XML序列化
private void button3_Click(object sender, EventArgs e)
{
List<Product> product = new List<Product>();
product.Add(new Product(1, "spiky pung", 1000.0, "Good stuff."));
product.Add(new Product(2, "Gloop Galloop Soup", 25.0, "Tasty."));
product.Add(new Product(4, "Hat Sauce", 12.0, "One for the kids."));
FileStream stream=new FileStream(@"users.xml", FileMode.Create);
System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(product.GetType());
ser.Serialize(stream, product);
stream.Close();
}
//XML反序列化
private void button4_Click(object sender, EventArgs e)
{
List<Product> saveProduct = new List<Product>();
System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(saveProduct.GetType());
FileStream stream = new FileStream(@"users.xml", FileMode.Open);
saveProduct = ser.Deserialize(stream) as List<Product>;
foreach (Product pro in saveProduct)
{
label1.Text += pro.ToString();
}
stream.Close();
}
}
}
代码不再说明,看的懂的就OK,看不动可以在下面给我留言,再做解释
如果要求具有可移植性,请使用 SoapFormatter。所要做的更改只是将以上代码中的BinaryFormatter换 SoapFormatter,而 Serialize 和 Deserialize 调用不变。