C# 二进制序列化和反序列化(初探)

2022/2/7 9:12:38

本文主要是介绍C# 二进制序列化和反序列化(初探),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

一、前言

  在用C语言编程的时候,如果要通过网络或者串口等接口传输一个结构体,通常会将这个结构体指针强转成char类型的指针,然后以char类型传输,在另外一边将接收到的数据的指针再转成想要的结构体指针即可。在C#里显然是不能用这种方法操作的。如果用C#编程,可以将需要传输的对象序列化,再另外一边再进行反序列化。

二、二进制序列化

  将一个数据进行二进制序列化需要用到的类为:BinaryFormatter,需要引用的命名空间为:System.Runtime.Serialization.Formatters.Binary;

  二进制序列化方法:void Serialize(Stream serializationStream, object graph);

  该方法的作用是将graph序列化到指定的流。为了测试方便,可以使用FileStream对象(因为FileStream继承自Stream)以文件的形式存储在本地。如果序列化的是一个自定义类对象,那么该类需要用[Serializable]标记,否则程序运行时会抛出异常。

  测试代码如下:

using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

namespace Suzkfly
{
    class Program
    {
        static void Main(string[] args)
        {
            Person zhangsan = new Person();
            BinaryFormatter bf = new BinaryFormatter();

            using (FileStream fs = File.Create(@"C:\Users\Suzkfly\Desktop\file_test\1.txt"))
            {
                bf.Serialize(fs, zhangsan);
            }
        }
    }
  
    [Serializable]
    public class Person
    {
        private int age = 18;
        private char gender = '男';
        private string name = "张三";
    }
}

  程序运行完之后在我传入的那个路径下就出现了1.txt,打开里面的内容大部分是乱码,但能看到里面有age,gender,name这些字符串。

三、二进制反序列化

  二进制的反序列化就是序列化的逆过程,具体内容就不多说了,直接上测试代码,这次测试使用的1.txt就是上一章生成的,但在代码里我故意使了一些坏:

using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

namespace Suzkfly
{
    class Program
    {
        static void Main(string[] args)
        {
            Person zhangsan = new Person();
            BinaryFormatter bf = new BinaryFormatter();

            using (FileStream fs = File.OpenRead(@"C:\Users\Suzkfly\Desktop\file_test\1.txt"))
            {
                zhangsan = (Person)bf.Deserialize(fs);
            }

            Console.WriteLine("zhangsan.age = {0}", zhangsan.age);
            Console.WriteLine("zhangsan.gender = {0}", zhangsan.gender);
            Console.WriteLine("zhangsan.name = {0}", zhangsan.name);

            Console.ReadKey();
        }
    }

    [Serializable]
    public class Person
    {
        public string name;
        public char gender;
        public int age;
    }
}

  反序列化也要在类上标记[Serializable],不然运行时会抛出异常。代码中我“使坏”的地方有2处,第一是将每个字段的访问修饰符由private改成了public,第二是调换了三个字段的顺序,但是程序的运行结果是喜人的:

  

 

   但是不能改变类名,否则程序运行时会抛出异常。如果改变了字段名,但是位置不改变,如将"age",改成"egg",那么程序可以正常运行,egg的值不会变成age的值。这说明反序列化是用类名和字段名去精确匹配的,不会受字段的访问级别和顺序的影响。

四、不序列化

  可以在已经被[Serializable]标记过的类中的字段前,用[NonSerialized]表示这个字段不被序列化(也不能反序列化)。

  测试程序:

using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

namespace Suzkfly
{
    class Program
    {
        static void Main(string[] args)
        {
            Person zhangsan = new Person();
            BinaryFormatter bf = new BinaryFormatter();

            using (FileStream fs = File.OpenRead(@"C:\Users\Suzkfly\Desktop\file_test\1.txt"))
            {
                zhangsan = (Person)bf.Deserialize(fs);
            }

            Console.WriteLine("zhangsan.age = {0}", zhangsan.Age);
            Console.WriteLine("zhangsan.gender = {0}", zhangsan.Gender);
            Console.WriteLine("zhangsan.name = {0}", zhangsan.Name);

            Console.ReadKey();
        }
    }

    [Serializable]
    public class Person
    {
        private string name;
        private char gender;
        [NonSerialized]
        private int age = 0;

        public string Name
        {
            get
            {
                return name;
            }
        }
        public char Gender
        {
            get
            {
                return gender;
            }
        }
        public int Age
        {
            get
            {
                return age;
            }
        }
    }
}

  在该程序中使用的序列化的文件中是有age这个字段的,但是因为运行的程序中age是被[NonSerialized]标记的,因此运行的结果,age的值仍然是0。

  

 



这篇关于C# 二进制序列化和反序列化(初探)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程