ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2022-02-07 02:02:22  阅读:166  来源: 互联网

标签:C# age Person 初探 using 序列化 zhangsan public


一、前言

  在用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#,age,Person,初探,using,序列化,zhangsan,public
来源: https://www.cnblogs.com/Suzkfly/p/15866778.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有