.net序列化及反序列化

序列化是指一个对象的实例可以被保存,保存成一个二进制串,当然,一旦被保存成二进制串,那么也可以保存成文本串了。
比如,一个计数器,数值为2,我们可以用字符串“2”表示。
如果有个对象,叫做connter,当前值为2,那么可以序列化成“2”,反向的,也可以从“2”得到值为2的计数器实例。
这样,关机时序列化它,开机时反序列化它,每次开机都是延续的。不会都是从头开始。

序列化概念的提出和实现,可以使我们的应用程序的设置信息保存和读取更加方便。

序列化有很多好处,比如,在一台机器上产生一个实例,初始化完毕,然后可以序列化,通过网络传送到另一台机器,然后反序列化,得到对象实例,之后再执行某些业务逻辑,得到结果,再序列化,返回第一台机器,第一台机器得到对象实例,得到结果。
这个例子是目前比较先进的“智能代理”的原理。

当前比较热火的web services使用soap协议,soap协议也是以对象的可序列化为基础的。

一 概述
.NET Framework为处理XML数据提供了许多不同的类库。XmlDocument类能让你像处理文件一样处理xml数据,而XmlReader、XmlWriter和它们的派生类使你能够将xml数据作为数据流处理。
XmlSerializer则提供了另外的方法,它使你能够将自己的对象串行化和反串行化为xml。串行化数据既能够让你像处理文件一样对数据进行随机处理,同时又能跳过你不感兴趣的数据。
二 主要类库介绍
   .NET 支持对象xml序列化和反序列化的类库主要位于命名空间System.Xml.Serialization中。
   1.  XmlSerializer 类
   该类用一种高度松散耦合的方式提供串行化服务。你的类不需要继承特别的基类,而且它们也不需要实现特别的接口。相反,你只需在你的类或者这些类的公共域以及读/写属性里加上自定义的特性。XmlSerializer通过反射机制读取这些特性并用它们将你的类和类成员映射到xml元素和属性。
   2. XmlAttributeAttribute 类
   指定类的公共域或读/写属性对应xml文件的Attribute。
   例:[XmlAttribute(“type”)] or [XmlAttribute(AttributeName=”type”)]
   3. XmlElementAttribute类
   指定类的公共域或读/写属性对应xml文件的Element。
   例:[XmlElement(“Maufacturer”)] or [XmlElement(ElementName=”Manufacturer”)]
   4. XmlRootAttribute类
   Xml序列化时,由该特性指定的元素将被序列化成xml的根元素。
   例:[XmlRoot(“RootElement”)] or [XmlRoot(ElementName = “RootElements”)]
   5. XmlTextAttribute 类
   Xml序列化时,由该特性指定的元素值将被序列化成xml元素的值。一个类只允许拥有一个该特性类的实例,因为xml元素只能有一个值。
   6. XmlIgnoreAttribute类
   Xml序列化时不会序列化该特性指定的元素。
三 实例
   下面例子中的xml schema 描述了一个简单的人力资源信息,其中包含了xml的大部分格式,如xml 元素相互嵌套, xml元素既有元素值,又有属性值。
   1. 待序列化的类层次结构
    [XmlRoot("humanResource")]
    public class HumanResource
    {
        #region private data.
        private int m_record = 0;
        private Worker[] m_workers = null;
        #endregion
 
        [XmlAttribute(AttributeName="record")]
        public int Record
        {
            get { return m_record; }
            set { m_record = value; }
        }
 
        [XmlElement(ElementName="worker")]
        public Worker[] Workers
        {
            get { return m_workers; }
            set { m_workers = value; }
        }
}
 
    public class Worker
    {
        #region private data.
        private string m_number = null;
        private InformationItem[] m_infoItems = null;
        #endregion
 
        [XmlAttribute("number")]
        public string Number
        {
            get { return m_number; }
            set { m_number = value; }
        }
 
        [XmlElement("infoItem")]
        public InformationItem[] InfoItems
        {
            get { return m_infoItems; }
            set { m_infoItems = value; }
        }
}
 
    public class InformationItem
    {
        #region private data.
        private string m_name = null;
        private string m_value = null;
        #endregion
 
        [XmlAttribute(AttributeName = "name")]
        public string Name
        {
            get { return m_name; }
            set { m_name = value; }
        }
 
        [XmlText]
        public string Value
        {
            get { return m_value; }
            set { m_value = value; }
        }
}
   2. 序列化生成的xml结构
       <?xml version="1.0" ?>
- <humanResource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"record="2">
- <worker number="001">
                 <infoItem name="name">Michale</infoItem>
                 <infoItem name="sex">male</infoItem>
                 <infoItem name="age">25</infoItem>
            </worker>
- <worker number="002">
                 <infoItem name="name">Surce</infoItem>
                 <infoItem name="sex">male</infoItem>
                 <infoItem name="age">28</infoItem>
           </worker>
         </humanResource>
   3. 利用XmlSerializer类进行序列化和反序列化的实现(一般利用缓存机制实现xml文件只解析一次。)
    public sealed class ConfigurationManager
    {
        private static HumanResource m_humanResource = null;
        private ConfigurationManager(){}
 
        public static HumanResource Get(string path)
        {
            if (m_humanResource == null)
            {
                FileStream fs = null;
                try
                {
                    XmlSerializer xs = new XmlSerializer(typeof(HumanResource));
                    fs = new FileStream(path, FileMode.Open, FileAccess.Read);
                    m_humanResource = (HumanResource)xs.Deserialize(fs);
                    fs.Close();
                    return m_humanResource;
                }
                catch
                {
                    if (fs != null)
                        fs.Close();
                    throw new Exception("Xml deserialization failed!");
                }
 
            }
            else
            {
                return m_humanResource;
            }
        }
 
        public static void Set(string path, HumanResource humanResource)
        {
            if (humanResource == null)
                throw new Exception("Parameter humanResource is null!");
           
            FileStream fs = null;
            try
            {
                XmlSerializer xs = new XmlSerializer(typeof(HumanResource));
                fs = new FileStream(path, FileMode.Create, FileAccess.Write);
                xs.Serialize(fs, humanResource);
                m_humanResource = null;
                fs.Close();
            }
            catch
            {
                if (fs != null)
                    fs.Close();
                throw new Exception("Xml serialization failed!");
            }
        }
    }
四 说明
   1. 需要序列化为xml元素的属性必须为读/写属性;
   2. 注意为类成员设定缺省值,尽管这并不是必须的。

“序列化”可被定义为将对象的状态存储到存储媒介中的过程。在此过程中,对象的公共字段和私有字段以及类的名称(包括包含该类的程序集)都被转换为字节流,然后写入数据流。在以后“反序列化”该对象时,创建原始对象的精确复本。
一、为什么要选择序列化
    一个原因是将对象的状态保持在存储媒体中,以便可以在以后重新创建精确的副本
    另一个原因是通过值将对象从一个应用程序域发送到另一个应用程序域中
    例如,序列化可用于在 ASP.NET 中保存会话状态并将对象复制到 Windows 窗体的剪贴板中。远程处理还可以使用序列化通过值将对象从一个应用程序域传递到另一个应用程序域中。
二、如何实现对象的序列化及反序列化
    要实现对象的序列化,首先要保证该对象可以序列化。而且,序列化只是将对象的属性进行有效的保存,对于对象的一些方法则无法实现序列化的。
    实现一个类可序列化的最简便的方法就是增加Serializable属性标记类。如:
    [Serializable()]
    public class MEABlock
    {
        private int m_ID;
        public string Caption;

public MEABlock()
        {
            ///构造函数
        }
    }
    即可实现该类的可序列化。
    要将该类的实例序列化为到文件中?.NET FrameWork提供了两种方法:
    1、XML序列化
        使用 XmLSerializer 类,可将下列项序列化。

  • 公共类的公共读/写属性和字段
  • 实现 ICollection 或 IEnumerable 的类。(注意只有集合会被序列化,而公共属性却不会。)
  • XmlElement 对象。
  • XmlNode 对象。
  • DataSet 对象。

要实现上述类的实例的序列化,可参照如下例子:
        MEABlock myBlock = new MEABlock();
        // Insert code to set properties and fields of the object.
        XmlSerializer mySerializer = new XmlSerializer(typeof(MEABlock));
        // To write to a file, create a StreamWriter object.
        StreamWriter myWriter = new StreamWriter("myFileName.xml");
        mySerializer.Serialize(myWriter, MEABlock);
    需要注意的是XML序列化只会将public的字段保存,对于私有字段不予于保存。
    生成的XML文件格式如下:
        <MEABlock>
            <Caption>Test</Caption>
        </MEABlock>
    对于对象的反序列化,则如下:
        MEABlock myBlock;
        // Constructs an instance of the XmlSerializer with the type
        // of object that is being deserialized.
        XmlSerializer mySerializer = new XmlSerializer(typeof(MEABlock));
        // To read the file, creates a FileStream.
        FileStream myFileStream = new FileStream("myFileName.xml", FileMode.Open);
        // Calls the Deserialize method and casts to the object type.
        myBlock = (MEABlock)mySerializer.Deserialize(myFileStream)
    2、二进制序列化
        与XML序列化不同的是,二进制序列化可以将类的实例中所有字段(包括私有和公有)都进行序列化操作。这就更方便、更准确的还原了对象的副本。
        要实现上述类的实例的序列化,可参照如下例子:
        MEABlock myBlock = new MEABlock();
        // Insert code to set properties and fields of the object.
        IFormatter formatter = new BinaryFormatter();
        Stream stream = new FileStream("MyFile.bin",FileMode.Create,FileAccess.Write, FileShare.None);
        formatter.Serialize(stream, myBlock);
        stream.Close();
    对于对象的反序列化,则如下:
        IFormatter formatter = new BinaryFormatter();
        Stream stream = new FileStream("MyFile.bin", FileMode.Open,FileAccess.Read, FileShare.Read);
        MEABlock myBlock = (MEABlock) formatter.Deserialize(stream);
        stream.Close();

三、如何变相实现自定义可视化控件的序列化、反序列化
        对于WinForm中自定义控件,由于继承于System.Windows.Form类,而Form类又是从MarshalByRefObject继承的,窗体本身无法做到序列化,窗体的实现基于Win32下GUI资源,不能脱离当前上下文存在。
        当然可以采用变通的方法实现控件的序列化。这里采用的是记忆类模型
        定义记忆类(其实就是一个可序列化的实体类)用于记录控件的有效属性,需要序列化控件的时候,只需要将该控件的实例Copy到记忆类,演变成序列化保存该记忆类的操作。
        反序列化是一个逆过程。将数据流反序列化成为该记忆类,再根据该记忆类的属性生成控件实例。而对于控件的一些事件、方法则可以继续使用。

 

C#: .net序列化及反序列化 [XmlElement(“节点名称”)] [XmlAttribute(“节点属性”)] (上篇)的更多相关文章

  1. C#: .net序列化及反序列化 [XmlElement(“节点名称”)] [XmlAttribute(“节点属性”)] (下篇)

    介绍 XML 序列化 .NET Framework 开发员指南   序列化是将对象转换为容易传输的格式的过程.例如,可以序列化一个对象,然后使用 HTTP 通过 Internet 在客户端和服务器之间 ...

  2. 【转】JavaScript获取节点类型、节点名称和节点值

    DOM节点信息包括节点类型(nodeType).节点名称(nodeName)和节点值(nodeValue). 节点类型 DOM节点中,每个节点都拥有不同的类型.W3C规范中常用的 DOM节点类型有以下 ...

  3. JavaScript判断对象类型及节点类型、节点名称和节点值

    一.JavaScript判断对象类型 1.可以使用typeof函数判断对象类型 function checkObject1(){ var str="str"; console.lo ...

  4. tensorflow 根据节点名称获取节点

    ckpt_file = os.path.join(self.args.bert_dir, 'model.ckpt-6123') # 获取图的reader reader = self.tf_instan ...

  5. C#: .net序列化及反序列化 [XmlElement(“节点名称”)]

    .net序列化及反序列化 序列化是指一个对象的实例可以被保存,保存成一个二进制串,当然,一旦被保存成二进制串,那么也可以保存成文本串了.比如,一个计数器,数值为2,我们可以用字符串“2”表示.如果有个 ...

  6. 重新想象 Windows 8 Store Apps (60) - 通信: 获取网络信息, 序列化和反序列化

    [源码下载] 重新想象 Windows 8 Store Apps (60) - 通信: 获取网络信息, 序列化和反序列化 作者:webabcd 介绍重新想象 Windows 8 Store Apps ...

  7. SpringBoot系列: Json的序列化和反序列化

    ============================= 控制 json 序列化/反序列化=============================1. @JsonIgnoreProperties的 ...

  8. C#对象序列化与反序列化zz

      C#对象序列化与反序列化(转载自:http://www.cnblogs.com/LiZhiW/p/3622365.html) 1. 对象序列化的介绍........................ ...

  9. XML序列化和反序列化

    上篇总结了下JSON的序列化和反序列化,博园中大牛给了很多牛叉的评论,学习了不少. 不过在上篇中忘了把json序列化和反序列化的另外一种方式写上去了,这里做个简单的补充: Json篇:http://w ...

随机推荐

  1. Solution -「Gym 102956A」Belarusian State University

    \(\mathcal{Description}\)   Link.   给定两个不超过 \(2^n-1\) 次的多项式 \(A,B\),对于第 \(i\in[0,n)\) 个二进制位,定义任意一个二元 ...

  2. Solution -「多校联训」染色

    \(\mathcal{Description}\)   Link.   给定 \(n\) 和 \(q\) 次询问,每次询问给出 \(x,k\),求第 \(x\) 位为 0 且任意两个 1 的下标之差不 ...

  3. Python基础—函数(Day9)

    一.函数的定义 def 关键字,定义一个函数 my_len 函数名(书写规则与变量名一样) def与函数名中间一个空格. def与函数名中间一个空格. 函数名():加冒号 函数体 my_len()#函 ...

  4. MySQL是怎么保证redo log和binlog是完整的?

    摘要:WAL机制保证只要redo log和binlog保证持久化到磁盘,就能确保MySQL异常重启后,数据可以恢复. 本文分享自华为云社区<MySQL会丢数据吗?>,作者: JavaEdg ...

  5. CobaltStrike逆向学习系列(12):RDI 任务发布流程分析

    这是[信安成长计划]的第 12 篇文章 0x00 目录 0x01 任务构建 0x02 结果处理 0x03 功能 DLL 分析 之前的分析都是针对整个 CS 的框架来进行的,但是功能也是整个 C2 中相 ...

  6. nessus安装破解

    Nessus2.0-20211012插件包 Nessus-8.15.2-x64.msi 0x01 Nessus更新介绍 Nessus下载地址 1https://www.tenable.com/down ...

  7. 帆软思迈特软件Smartbi两家区别在哪里?

    简单介绍下,从前端展现市场来看,国内这几年帆软算是做的比较好的一家公司,整体市场营销,以及产品易用性也是不错.思迈特公司也是一家专门从事做数据分析平台的公司,也有接近20年的历史,早期从银行.金融证券 ...

  8. 2021年国内BI厂商推荐_大数据分析工具

    随着互联网大数据时代的不断发展,BI让企业的工作效率变得更高效.BI的功能也随着需求的增长不断地丰富,例如,数据可视化大屏.可视化表格.商业化数据分析.数据地图等.国外的厂商在很多场景下无法满足国内的 ...

  9. 使用Helm安装harbor

    使用nfs共享存储搭建的pvc(此次都放在一个vpc下): harbor使用nodePort方式部署,不使用ssl: 准备工作: 准备好harbor用的pvc: 安装好helm,添加好可用源: 因为使 ...

  10. C# 9.0元组 (ValueTuple)详细解说

    元组 (ValueTuple)类型是值类型:元组元素是公共字段,可以使用任意数量的元素定义元组.Tuple类型像一个口袋,在出门前可以把所需的任何东西一股脑地放在里面.您可以将钥匙.驾驶证.便笺簿和钢 ...