C#序列化与反序列化详解

什么是序列化以及如何实现序列化?

序列化是通过将对象转换为字节流,从而存储对象或将对象传输到内存,数据库或文件的过程。主要用途是保存对象的状态,包括对象的数据,以便能够在需要是重建对象。反向过程称为 反序列化。

 

如上图所示,对象 object 被序列化为 流,其中不仅包含数据、还包含对象类型的相关信息,如版本、区域性和程序集名称。然后可以将此流中的内容存储到数据库、文件或内存中。

 

序列化的用途:

通过序列化,可以执行如下操作:通过 Web 服务将对象发送到远程应用程序、在域之间传递对象、以 XML 字符串的形式传递对象通过防火墙、跨应用程序维护安全性或用户专属信息。

 

让对象可序列化:

需要具有对象、包含已序列化对象的一个流,以及一个 Fromatter。

System.Runtime.Serialization 包含序列化和反序列化对象所必须的类。

将 SerializableAttribute 特性应用于某个类型,以表示此类型的实例可以被序列化,如果对没有 SerializableAttribute 特性的类型进行序列化,则会引发异常。

如果想让类中的某个字段不可序列化,可以使用 NonSerializedAttribute 特性。

 

序列化的三种类型--二进制、XML、JSON

可以使用二进制 binary 或 XML 进行序列化,在 二进制序列化中,所有内容都会被序列化,且性能也很好,使用二进制编码来生成精简的序列化,可以用于基于存储或socket的网络流。

XML 序列化可提高可读性,以及对象共享和使用的灵活性,XML 序列化将对象的公共字段和属性或方法的参数和返回值序列化成符合特定 XML 格式的流,

System.Xml.Serialization 包含序列化和反序列化 XML 所需要的类

如果要保存运行程序过程的数据要么保存到数据库中,要么新建一个普通的文件,然后把数据保存进去.但是这两者有个缺点就是,不能把原有数据的结构也保存进去.比如一个类中的字段值保存进去后再读取出来必须再解析下才行.序列化技术让你省去了解析的过程.保存后再读取时直接得到一个class

序列化的方式有三种:BinaryFormatter,SoapFormatter,XmlSerializer

1.BinaryFormatter

保存成二进制数据流.用法示例:

using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
[Serializable]
//如果要想保存某个class中的字段,必须在class前面加个这样attribute(C#里面用中括号括起来的标志符)
public class Person
{
public int age;
public string name;
[NonSerialized] //如果某个字段不想被保存,则加个这样的标志
public string secret;
}

序列化:

classProgram
{
 staticvoid Main(string[] args)
{
Person person = newPerson();
person.age = 18;
person.name = "tom";
person.secret = "i will not tell you";
FileStream stream =newFileStream(@"c:\temp\person.dat",FileMode.Create);
BinaryFormatter bFormat =newBinaryFormatter();
bFormat.Serialize(stream, person);
stream.Close();
}




反序列化:

classProgram
{
staticvoid Main(string[] args)
{
Person person = newPerson();
FileStream stream =newFileStream(@"c:\temp\person.dat",FileMode.Open);
BinaryFormatter bFormat =newBinaryFormatter();
person = (Person)bFormat.Deserialize(stream);
//反序列化得到的是一个object对象.必须做下类型转换
stream.Close();
Console.WriteLine(person.age + person.name + person.secret);
//结果为18tom.因为secret没有有被序列化.
}




2.SoapFormatter

把数据保存成xml文件.里面除了保存的内容还有些额外的Soap信息.它的用法和BinaryFormatter一样.只要把BinaryFormatter都替换成SoapFormatter就行.

把文件名改为person.xml

另外就是添加名称空间:using System.Runtime.Serialization.Formatters.Soap;
这个名称空调对就的程序集有时VS没有自动引用.你必须手动去引用.选中project,右击选择Add Reference.在.NET的标签下选择

System.Runtime.Serialization.Formatters.Soap.然后点OK.

补充:SOAP(Simple Object Access Protocol )简单对象访问协议是在分散或分布式的环境中交换信息的简单的协议,是一个基于XML的协议,它包括四个部分:SOAP封装(envelop),封装定义了一个描述消息中的内容是什么,是谁发送的,谁应当接受并处理它以及如何处理它们的框架;SOAP编码规则(encoding rules),用于表示应用程序需要使用的数据类型的实例; SOAP RPC表示(RPC representation),表示远程过程调用和应答的协定;SOAP绑定(binding),使用底层协议交换信息。

3.XmlSerializer

也是保存成XML文件.但没有其他额外信息.另外它只能保存public类型的字段.而其他两种类型能保存所有类型的字段.
这里仍使用上面的Person类.

实例1:

添加名称空间:

using System.IO;
using System.Xml.Serialization;

序列化:

classProgram
{
 staticvoid Main(string[] args)
{
Person person = newPerson();
person.age = 18;
person.name = "tom";
person.secret = "i will not tell you";
FileStream stream =newFileStream(@"c:\temp\xmlFormat.xml",FileMode.Create);
XmlSerializer xmlserilize = newXmlSerializer(typeof(Person));
xmlserilize.Serialize(stream, person);
stream.Close();
}




反序列化:

classProgram
{
staticvoid Main(string[] args)
{
Person person = newPerson();
FileStream stream =newFileStream(@"c:\temp\xmlFormat.xml",FileMode.Open);
XmlSerializerxmlserilize = newXmlSerializer(typeof(Person));
person = (Person)xmlserilize.Deserialize(stream);
stream.Close();
Console.WriteLine(person.age + person.name + person.secret);
}




指定 XML 标签的名字

[XmlRoot(department)]
public class Department {
    public string DeptName { get; set; }


    [XmlElement("extra")]
    public DeptExtraInfo DeptExtraInfo { get; set; }
}

通过在 XmlRoot、XmlElement 后面加上一个括号即可实现,其中XmlRoot用于指定“根”,也就是XML的最上一层的Tag

指定 XML 标签的属性

[XmlRoot("department")]
public class Department {
    public string DeptName { get; set; } = "研发部";


    [XmlAttribute("timestamp")]
    public int Timestamp = 10;
}

Timestamp就成为了department这个根节点的timestamp属性。

实例2:

public class Book  
{  
    public String title;  
}         
  
public void ReadXML()  
{  
    // First write something so that there is something to read ...  
    var b = new Book { title = "Serialization Overview" };  
    var writer = new System.Xml.Serialization.XmlSerializer(typeof(Book));  
    var wfile = new System.IO.StreamWriter(@"c:\temp\SerializationOverview.xml");  
    writer.Serialize(wfile, b);  
    wfile.Close();  
  
    // Now we can read the serialized book ...  
    System.Xml.Serialization.XmlSerializer reader =   
        new System.Xml.Serialization.XmlSerializer(typeof(Book));  
    System.IO.StreamReader file = new System.IO.StreamReader(  
        @"c:\temp\SerializationOverview.xml");  
    Book overview =  (Book)reader.Deserialize(file);  
    file.Close();  
  
    Console.WriteLine(overview.title);  
  
}

传统方法生成xml:(超链接)

C#在WINForm程序中创建XML文件

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C#中,序列化是将对象转换为字节流的过程,而反序列化是将字节流转换回对象的过程。C#提供了多种序列化反序列化的方式,其中最常用的是使用BinaryFormatter类进行二进制序列化反序列化。该类可以将对象序列化为简洁的字节流,并能够通过相同的格式化程序进行反序列化。 在序列化一个对象时,BinaryFormatter会将对象的类名、程序集和所有数据成员写入存储中。它还会处理对象之间的引用关系,确保同一对象不会被多次序列化。需要注意的是,被序列化的对象引用的所有对象都必须标记为Serializable,否则在序列化未标记的对象时会引发异常。 反序列化时,BinaryFormatter会根据序列化时写入的对象信息,将字节流转换回对象。反序列化过程中不会调用构造函数,这是为了性能考虑所做的约束。 要使用BinaryFormatter进行序列化反序列化,您需要创建一个流的实例和一个BinaryFormatter实例,并使用Serialize方法将对象序列化为字节流,将流和对象作为参数传递给Serialize方法。 需要注意的是,C#还提供了其他序列化反序列化的方式,例如XML序列化和JSON序列化,它们分别使用XmlSerializer类和JsonSerializer类。这些类对于特定的序列化需求可能更加适用,但在一般情况下,使用BinaryFormatter是一种简单且高效的方式进行对象的序列化反序列化。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [C# - 序列化反序列化](https://blog.csdn.net/dodream/article/details/4729415)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值