序列化是将对象或对象图转换成字节流的过程。其中所有对象都是以流的方式进行传输或保存的。
对象图是指一个对象包含多个对象,这样一来,不同的对象便相互连接起来了。
常见的例子有:
- 一组对象可轻松复制到系统的剪切板,再粘贴回同一个或另一个应用程序。
- 一组对象可克隆并放到一边作为"备份";与此同时,用户操纵一组"主"对象。
- 一组对象可轻松地通过网路发送给另一台机器上运行的进程。
序列化/反序列化快速入门
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
namespace RuntimeSerialization
{
class Program
{
static void Main(string[] args)
{
var objectGraph = new List<String> { "Jeff", "Kristin", "Aidan", "Grant"};
Stream stream = SerializeToMemory(objectGraph);
//反序列化前,要定位到内存流的起始位置
stream.Position = 0;
objectGraph = (List<String>)DeserializeFromMemory(stream);
foreach (var s in objectGraph) Console.WriteLine(s);
Console.ReadLine();
}
private static MemoryStream SerializeToMemory(Object objectGraph) {
//构造流来容纳序列化的对象
MemoryStream stream = new MemoryStream();
//构造序列化格式化器来执行所有真正的工作
BinaryFormatter formatter = new BinaryFormatter();
//告诉格式化器将对象序列化到流中,传递的第一个参数,为对流对象的引用,流对象标识了序列化好的字节应放在哪里,它可以是从System.IO。Stream抽象基类派生的任何类型的对象。也就是说,对象图可以序列化成一个FileStream或者NetworkStream等。
formatter.Serialize(stream, objectGraph);
return stream;
}
private static Object DeserializeFromMemory(Stream stream) {
//构造序列化格式化器来做所有真正的工作
BinaryFormatter formatter = new BinaryFormatter();
//从流中反序列化对象
return formatter.Deserialize(stream);
}
}
}
浅拷贝是指源对象与拷贝对象共用一份实体,仅仅是引用的变量不同(名称不同)。
深拷贝是指源对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响。
可以利用序列化创建对象的深拷贝(或者说克隆体):
private static Object DeepClone(Object original) {
//构造临时内存流
using (MemoryStream stream = new MemoryStream()) {
BinaryFormatter formatter = new BinaryFormatter();
formatter.Context = new StreamingContext(StreamingContextStates.Clone);
formatter.Serialize(stream, original);
stream.Position = 0;
//向调用者返回对象图(深拷贝)的根
return formatter.Deserialize(stream);
}
}
下面写客户端代码:
static void Main(string[] args)
{
StringBuilder stringBuilder1 = new StringBuilder("stringBuilder1");
StringBuilder stringBuilder2 = stringBuilder1;
StringBuilder stringBuilder3 = (StringBuilder)DeepClone(stringBuilder1);
stringBuilder2.AppendFormat("{0}{1}",
Environment.NewLine, "stringBuilder2");
stringBuilder3.AppendFormat("{0}{1}",
Environment.NewLine, "stringBuilder3");
Console.WriteLine(stringBuilder1);
Console.ReadLine();
}
运行结果:
很明显,深拷贝stringBuilder1的stringBuilder3对象追加了字符串,在输出stringBuilder1对象时并没有显示出来。
其次,还可以将多个对象图序列化到一个流中,这是很有用的一个操作。
private static List<Customer> s_customers = new List<Customer>();
private static List<Order> s_order1 = new List<Order>();
private static List<Order> s_order2 = new List<Order>();
private static void SaveApplicationState(Stream stream) {
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, s_customers);
formatter.Serialize(stream, s_order1);
formatter.Serialize(stream, s_order2);
}
private static void RestoreApplicationState(Stream stream) {
BinaryFormatter formatter = new BinaryFormatter();
//反序列化应用程序的完整状态(和序列化时的顺序一样)
s_customers = (List<Customer>)formatter.Deserialize(stream);
s_order1 = (List<Order>)formatter.Deserialize(stream);
s_order2 = (List<Order>)formatter.Deserialize(stream);
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。