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# 二进制序列化和反序列化(初探)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2022-03-01沐雪多租宝商城源码从.NetCore3.1升级到.Net6的步骤
- 2024-12-06使用Microsoft.Extensions.AI在.NET中生成嵌入向量
- 2024-11-18微软研究:RAG系统的四个层次提升理解与回答能力
- 2024-11-15C#中怎么从PEM格式的证书中提取公钥?-icode9专业技术文章分享
- 2024-11-14云架构设计——如何用diagrams.net绘制专业的AWS架构图?
- 2024-05-08首个适配Visual Studio平台的国产智能编程助手CodeGeeX正式上线!C#程序员必备效率神器!
- 2024-03-30C#设计模式之十六迭代器模式(Iterator Pattern)【行为型】
- 2024-03-29c# datetime tryparse
- 2024-02-21list find index c#
- 2024-01-24convert toint32 c#