深入C#学习系列一:序列化(Serialize)、反序列化(Deserialize)

深入C#学习系列一:序列化(Serialize)、反序列化(Deserialize)

序列化又称串行化,是.NET运行时环境用来支持用户定义类型的流化的机制。其目的是以某种存储形成使自定义对象持久化,或者将这种对象从一个地方传输到另一个地方。
    .NET框架提供了两种串行化的方式:1、是使用BinaryFormatter进行串行化;2、使用SoapFormatter进行串行化;3、使用XmlSerializer进行串行化。第一种方式提供了一个简单的二进制数据流以及某些附加的类型信息,而第二种将数据流格式化为XML存储;第三种其实和第二种差不多也是XML的格式存储,只不过比第二种的XML格式要简化很多(去掉了SOAP特有的额外信息)。
    可以使用[Serializable]属性将类标志为可序列化的。如果某个类的元素不想被序列化,1、2可以使用[NonSerialized]属性来标志,2、可以使用[XmlIgnore]来标志。
    1、使用BinaryFormatter进行串行化
    下面是一个可串行化的类:
    
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.IO;
using
 System.Runtime.Serialization.Formatters.Binary;
/**//// <summary>
/// ClassToSerialize 的摘要说明
/// </summary>

[Serializable]
public class ClassToSerialize
{
    
public int id = 100;
    
public string name = "Name";
    [NonSerialized]
    
public string Sex = "";
}


    下面是串行化和反串行化的方法:
    
public void SerializeNow()
    
{
        ClassToSerialize c 
= new ClassToSerialize();
        FileStream fileStream 
= new FileStream("c:\\temp.dat", FileMode.Create);
        BinaryFormatter b 
= new BinaryFormatter();
        b.Serialize(fileStream, c);
        fileStream.Close();
    }

    
public void DeSerializeNow()
    
{
        ClassToSerialize c 
= new ClassToSerialize();
        c.Sex 
= "kkkk";
        FileStream fileStream 
= new FileStream("c:\\temp.dat", FileMode.Open, FileAccess.Read, FileShare.Read);
        BinaryFormatter b 
= new BinaryFormatter();
        c 
= b.Deserialize(fileStream) as ClassToSerialize;
          Response.Write(c.name);
        Response.Write(c.Sex);
        fileStream.Close();
    }

    调用上述两个方法就可以看到串行化的结果:Sex属性因为被标志为[NonSerialized],故其值总是为null。
    2、使用SoapFormatter进行串行化
    和BinaryFormatter类似,我们只需要做一下简单修改即可:
    a.将using语句中的.Formatter.Binary改为.Formatter.Soap;
    b.将所有的BinaryFormatter替换为SoapFormatter.
    c.确保报存文件的扩展名为.xml
    经过上面简单改动,即可实现SoapFormatter的串行化,这时候产生的文件就是一个xml格式的文件。
    3、使用XmlSerializer进行串行化
    关于格式化器还有一个问题,假设我们需要XML,但是不想要SOAP特有的额外信息,那么我们应该怎么办呢?有两中方案:要么编写一个实现IFormatter接口的类,采用的方式类似于SoapFormatter类,但是没有你不需要的信息;要么使用库类XmlSerializer,这个类不使用Serializable属性,但是它提供了类似的功能。
    如果我们不想使用主流的串行化机制,而想使用XmlSeralizer进行串行化我们需要做一下修改:
    a.添加System.Xml.Serialization命名空间。
    b.Serializable和NoSerialized属性将被忽略,而是使用XmlIgnore属性,它的行为与NoSerialized类似。
    c.XmlSeralizer要求类有个默认的构造器,这个条件可能已经满足了。
    下面看示例:
    要序列化的类:
    
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Serialization;
[Serializable]
public class Person
{
    
private string name;
    
public string Name
    
{
        
get
        
{
            
return name;
        }

        
set
        
{
            name 
= value;
        }

    }



    
public string Sex;
    
public int Age = 31;
    
public Course[] Courses;

    
public Person()
    
{
    }

    
public Person(string Name)
    
{
        name 
= Name;
        Sex 
= "";
    }

}

[Serializable]
public class Course
{
    
public string Name;
    [XmlIgnore]
    
public string Description;
    
public Course()
    
{
    }

    
public Course(string name, string description)
    
{
        Name 
= name;
        Description 
= description;
    }

}
  

    序列化和反序列化方法:
public void XMLSerialize()
    
{
        Person c 
= new Person("cyj");
        c.Courses 
= new Course[2];
        c.Courses[
0= new Course("英语""交流工具");
        c.Courses[
1= new Course("数学","自然科学");
        XmlSerializer xs 
= new XmlSerializer(typeof(Person));
        Stream stream 
= new FileStream("c:\\cyj.XML",FileMode.Create,FileAccess.Write,FileShare.Read);
        xs.Serialize(stream,c);
        stream.Close();
    }

    
public void XMLDeserialize()
    
{
        XmlSerializer xs 
= new XmlSerializer(typeof(Person));
        Stream stream 
= new FileStream("C:\\cyj.XML",FileMode.Open,FileAccess.Read,FileShare.Read);
        Person p 
= xs.Deserialize(stream) as Person;
        Response.Write(p.Name);
        Response.Write(p.Age.ToString());
        Response.Write(p.Courses[
0].Name);
        Response.Write(p.Courses[
0].Description);
        Response.Write(p.Courses[
1].Name);
        Response.Write(p.Courses[
1].Description);
        stream.Close();
    }

这里Course类的Description属性值将始终为null,生成的xml文档中也没有该节点,如下图:
<?xml version="1.0"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  
<Sex></Sex>
  
<Age>31</Age>
  
<Courses>
    
<Course>
      
<Name>英语</Name>
      
<Description>交流工具</Description>
    
</Course>
    
<Course>
      
<Name>数学</Name>
      
<Description>自然科学</Description>
    
</Course>
  
</Courses>
  
<Name>cyj</Name>
</Person>

    4、自定义序列化
    如果你希望让用户对类进行串行化,但是对数据流的组织方式不完全满意,那么可以通过在自定义类中实现接口来自定义串行化行为。这个接口只有一个方法,GetObjectData. 这个方法用于将对类对象进行串行化所需要的数据填进SerializationInfo对象。你使用的格式化器将构造SerializationInfo对象,然后在串行化时调用GetObjectData. 如果类的父类也实现了ISerializable,那么应该调用GetObjectData的父类实现。
    如果你实现了ISerializable,那么还必须提供一个具有特定原型的构造器,这个构造器的参数列表必须与GetObjectData相同。这个构造器应该被声明为私有的或受保护的,以防止粗心的开发人员直接使用它。
    示例如下:
    实现ISerializable的类:
    
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
/**//// <summary>
/// Employee 的摘要说明
/// </summary>

[Serializable]
public class Employee:ISerializable
{
    
public int EmpId=100;
    
public string EmpName="刘德华";
    [NonSerialized]
    
public string NoSerialString = "NoSerialString-Test";
    
public Employee()
    
{
        
//
        
// TODO: 在此处添加构造函数逻辑
        
//
    }

    
private Employee(SerializationInfo info, StreamingContext ctxt)
    
{
        EmpId 
= (int)info.GetValue("EmployeeId"typeof(int));
        EmpName 
= (String)info.GetValue("EmployeeName",typeof(string));
        
//NoSerialString = (String)info.GetValue("EmployeeString",typeof(string));
    }

    
public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
    
{
        info.AddValue(
"EmployeeId", EmpId);
        info.AddValue(
"EmployeeName", EmpName);
        
//info.AddValue("EmployeeString", NoSerialString);
    }

}


    序列化和反序列化方法:
public void OtherEmployeeClassTest()
    
{
        Employee mp 
= new Employee();
        mp.EmpId 
= 10;
        mp.EmpName 
= "邱枫";
        mp.NoSerialString 
= "你好呀";
        Stream steam 
= File.Open("c:\\temp3.dat", FileMode.Create);
        BinaryFormatter bf 
= new BinaryFormatter();
        Response.Write(
"Writing Employee Info:");
        bf.Serialize(steam,mp);
        steam.Close();
        mp 
= null;
        
//反序列化
        Stream steam2 = File.Open("c:\\temp3.dat", FileMode.Open);
        BinaryFormatter bf2 
= new BinaryFormatter();
        Response.Write(
"Reading Employee Info:");
        Employee mp2 
= (Employee)bf2.Deserialize(steam2);
        steam2.Close();
        Response.Write(mp2.EmpId);
        Response.Write(mp2.EmpName);
        Response.Write(mp2.NoSerialString);
    }

转载于:https://www.cnblogs.com/smallstupidwife/archive/2011/12/08/2280326.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/549737.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

十一月·飘·立冬

十一月的南粤叶依然青翠在枝头与秋风和舞落叶遍地的诗意画面在博客生活逝如流年 渐走渐淡回忆飘然而来又飘然而去秋的最后一天放下回忆 飘去天涯飘不要说也不要问目光交错的一瞬注定了今生缘分此情可以见真心春风急 秋风也狠乱乱纷纷 是红尘浮浮沉沉 似幻似真金枝玉叶的结…

Centos 系统安装NetCore SDK命令以及一系列操作(1)

17年买的jesse老师的课程&#xff0c;虽然说NetCore出来很久了&#xff0c;自己打入行的时候就奔它去的&#xff0c;但。。。。废话不说了&#xff0c;还是自己做了再说吧&#xff0c; 首先需要一个Centos系统来让我们开始玩&#xff0c;下载地址&#xff1a;https://www.cento…

如何高效地判断奇数和偶数

在我们日常的编程当中&#xff0c;常常会遇到判断某个整数属于奇数还是偶数的情况。 大家一般的处理做法是用这个整数和2取模。然后判断是等于1还是等于0。 这里&#xff0c;我要为大家介绍一种快速有效的判断做法&#xff0c;利用2进制进行判断。 大家都知道&#xff0c;奇数的…

Windows Azure Traffic Manager (6) 使用Traffic Manager,实现本地应用+云端应用的高可用...

《Windows Azure Platform 系列文章目录》 注意&#xff1a;本文介绍的是使用国内由世纪互联运维的Azure China服务。 以前的Traffic Manager&#xff0c;背后的Service Endpoint必须是Azure数据中心的Cloud Service。 现在最新的Traffic Manager&#xff0c;Endpoint不仅仅支持…

Windows Azure Cloud Service (17) Role Endpoint

《Windows Azure Platform 系列文章目录》 在Windows Azure平台中&#xff0c;用户最多可以对以个Role指定5个Endpoint。而一个Hosted Service最多允许包含5个Role,所以说在一个Hosted Service中用户最多能定义25个Endpoint。 而对于每一个Endpoint&#xff0c;使用者需要设定如…

sentry + vue实现错误日志监控

起因 项目采用vue全家桶开发&#xff0c;现在拟嵌入sentry&#xff0c;实现对于线上网站进行错误日志记录。其实上传日志很简单&#xff0c;基本配置就可以了&#xff0c;但是上传配套的sourcemap则颇为费劲。这里记录一下使用心得。 实施步骤 上传日志 sentry使用文档&…

OSPF单域实验报告

1.1 实验任务<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />(1) 配置Loopback地址作为路由器的ID。(2) 配置OSPF的进程并在相应的接口上启用。(3) OSPF起来后&#xff0c;更新计时器。1.2 实验环境和网络拓扑<?xm…

sql server 2005 COUNT_BIG (Transact-SQL)

返回组中的项数。COUNT_BIG 的用法与 COUNT 函数类似。两个函数唯一的差别是它们的返回值。COUNT_BIG 始终返回 bigint 数据类型值。COUNT 始终返回 int 数据类型值。后面可能跟随 OVER 子句。 Transact-SQL 语法约定 语法 COUNT_BIG ( { [ ALL | DISTINCT ] expression } | * …

《浏览器播放RTSP方案》之 VLC插件播放RTSP视频流

VLC插件播放RTSP视频流多版本chrome安装安装vlc软件开启浏览器的NPAPI设置编写测试页插件设置其他问题最后目前网页对于RTSP流直接播放不支持&#xff0c;目前有插件和转流两种方式&#xff0c;这里针对vlc插件播放做一个简单的梳理。 查看官网教程 vlcWebPlugin, 得知其浏览器…

通过避免下列 10 个常见 ASP.NET 缺陷使网站平稳运行(转)

本文将讨论&#xff1a; • 缓存和 Forms 身份验证 • 视图状态和会话状态 • 配置文件属性序列化 • 线程池饱和 • 模拟和设置配置文件 本文使用了下列技术&#xff1a; .NET Framework、ASP.NET、Windows Server 2003 本页内容 LoadControl 和输出缓存会话和输出缓存Fo…

如何去掉DataTable中的重复行(新增.net 2.0中最新解决方法---简便)

.net 1.1中的解决方法(转)1建立一个DataSetHelper类(DataSetHelper.cs) publicclassDataSetHelper...{ public DataSet ds; public DataSetHelper(ref DataSet DataSet) ...{ ds DataSet; } public DataSetHelper() ...{ ds null; } p…

Centos 系统安装NetCore SDK命令以及一系列操作(2)

ok,接下来安装dotnetCore的SDK&#xff0c;访问&#xff1a;https://dotnet.microsoft.com/download&#xff0c; 如下图&#xff0c;选择Linux&#xff0c; 选择一下这个Linux的发行版&#xff0c;我们选择Centos就行&#xff0c;然后执行这些命令去安装SDK&#xff0c;地址如…

这该死的高度,height,clientHeight,scrollHeight,offsetHeight

引言: 虽然有时候界面的设置不是我们这些后台代码人员的工作,但是有时候却难以理解控件生成时的一些怪事,比方在学习webabcd的扩张GridView中固定列时,你或许已经被其中的height,clientHeight,scrollHeight,offsetheight弄得晕晕的了,当然这些都是网页制作的一个基础,将其记下,…

C#高级语法基础知识总结6——字符串集合

字符串 集合 列表声明 Var intListnew List<int>();Var racersnew List<Racer>();List<int> intListnew List<int>(10);//大小为10&#xff0c;倍数增加 使用Capacity属性可以获取和设置集合的容量 使用Count属性可以获取集合的元素个数 Add()方法添加…

浏览器播放rtsp视频流方案(vlc转http方案)

一.vlc播放器转成http&#xff0c;在浏览器用video标签播放 1.下载vlc播放器 网址:https://www.videolan.org/ 2.安装并打开之后&#xff0c;点击媒体 3.点击打开网络串流&#xff0c;进入到下个页面&#xff0c;在输入框输入自己的rtsp流 4.点击播放旁边的小三角号&#xff0c…

浏览器播放rtsp视频流方案(ffmpeg + nginx转m3u8)

1.下载ffmpeg &#xff0c;传送门&#xff1a;https://ffmpeg.en.softonic.com/ 2.配置环境变量 右击我的电脑---->点击属性&#xff0c;打开左侧高级系统设置 点击下方的环境变量 在下方系统变量中找到path变量&#xff0c;选中点击下方编辑&#xff0c;别点成删除&#…

浏览器播放rtsp视频流方案(ffmpeg + nginx转rtmp)

之前已经更新vlc和m3u8的方案了&#xff0c;这个是最后一个方案&#xff0c;同时&#xff0c;转rtmp的方案也是我在用的 1.下载ffmpeg &#xff0c;传送门&#xff1a;https://ffmpeg.en.softonic.com/ 2.配置环境变量 右击我的电脑---->点击属性&#xff0c;打开左侧高级…

uniapp+typeScript+vue3.0+vite

最近公司需要开发新版小程序&#xff0c;思考了一下&#xff0c;决定还是用最新的技术进行开发&#xff0c;同时也能锻炼到自己&#xff0c;废话不多说&#xff0c;开搞&#xff1a; 一.首先打开uniapp的官网&#xff1a;uni-app官网 //环境安装 //全局安装vue-cli npm instal…

纪中七日游——总结篇 DAY1AB

DAY 1 B 组 T1 游戏 Description Alice和Bob在玩一个游戏&#xff0c;游戏是在一个N*N的矩阵上进行的&#xff0c;每个格子上都有一个正整数。 当轮到Alice/Bob时&#xff0c;他/她可以选择最后一列或最后一行&#xff0c;并将其删除&#xff0c; 但必须保证选择的这一行或这一…

系列十一(实战)、发送 接收带标签的消息(Java操作RocketMQ)

一、发送 & 接收带标签的消息 1.1、概述 消息的种类纷繁复杂&#xff0c;不同的业务场景需要不同的消息&#xff0c;基于此RocketMQ提供了消息过滤功能&#xff0c;通过Tag或者Key进行区分&#xff0c;本章介绍Tag&#xff0c;我们再往一个Topic里面发送消息的时候&#x…