运行时序列化

序列化是将对象或对象图转换成字节流的过程。其中所有对象都是以流的方式进行传输或保存的。

对象图是指一个对象包含多个对象,这样一来,不同的对象便相互连接起来了。

常见的例子有:

  • 一组对象可轻松复制到系统的剪切板,再粘贴回同一个或另一个应用程序。
  • 一组对象可克隆并放到一边作为"备份";与此同时,用户操纵一组"主"对象。
  • 一组对象可轻松地通过网路发送给另一台机器上运行的进程。

序列化/反序列化快速入门

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 { "Jeff", "Kristin", "Aidan", "Grant"};
            Stream stream = SerializeToMemory(objectGraph);

            //反序列化前,要定位到内存流的起始位置
            stream.Position = 0;

            objectGraph = (List)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();
        }

运行结果:
运行时序列化_第1张图片

很明显,深拷贝stringBuilder1的stringBuilder3对象追加了字符串,在输出stringBuilder1对象时并没有显示出来。

其次,还可以将多个对象图序列化到一个流中,这是很有用的一个操作。

        private static List s_customers = new List();
        private static List s_order1 = new List();
        private static List s_order2 = new List();

        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)formatter.Deserialize(stream);
            s_order1 = (List)formatter.Deserialize(stream);
            s_order2 = (List)formatter.Deserialize(stream);
        }

你可能感兴趣的:(c#)