为什么要做序列化和反序列化?

一个回答:

我们都知道对象是不能在网络中直接传输的,不过还有补救的办法。XML(Extensible Markup Language)可扩展标记语言,本身就被设计用来存储数据,任何一个对象都可以用XML来描述。XML是可以作为对象信息的载体在网络中传输,因为它是文本形式的。
怎么进行XML文档与对象的相互转换呢?
XmlSerializer类就是干这个活的。
命名空间:System.Xml.Serialization
程序集:System.Xml(在 system.xml.dll 中)
现在这里展示了一个提供序列化与反序列化方法的EncodeHelper类(在文章最后,并且会讲解如何使用)。
Deserialize方法将XML字符串转换为指定类型的对象;(反序列化)
Serialize方法则将对象转换为XML字符串。(序列化)

另一个回答:

.Net程序执行时,对象都驻留在内存中;内存中的对象如果需要传递给其他系统使用;或者在关机时需要保存下来以便下次再次启动程序使用就需要序列化和反序列化。
 
这两个回答都是对的。
好了,现在我们来具体的看看XmlSerializer类的含义吧:
XmlSerializer类:将对象序列化到 XML 文档中和从 XML 文档中反序列化对象。XmlSerializer 使您得以控制如何将对象编码到 XML 中。
XML 序列化是将对象的公共属性 (Property)(如Student的Name属性)和字段转换为序列格式(这里是指 XML)以便存储或传输的过程。反序列化则是从 XML 输出中重新创建原始状态的对象。因此,可以将序列化视为将对象的状态保存到流或缓冲区的方法。例如,ASP.NET 使用 XmlSerializer 类对 XML Web services 消息进行编码。
 
范围:本文只介绍xml序列化,其实序列化可以是二进制的序列化,也可以是其他格式的序列化
 
看一段最简单的Xml序列化代码
class Program
{
static void Main(string[] args)
{
int i = 10;
//声明Xml序列化对象实例serializer
XmlSerializer serializer = new XmlSerializer(typeof(int));
//执行序列化并将序列化结果输出到控制台
serializer.Serialize(Console.Out, i);
Console.Read();
}
}

上面代码对int i进行了序列化,并将序列化的结果输出到了控制台,输出结果如下:

<?xml version="1.0" encoding="gb2312"?>
<int>10</int>

可以将上述序列化的xml进行反序列化,如下代码:

static void Main(string[] args)
{
using (StringReader rdr = new StringReader(@"<?xml version=""1.0"" encoding=""gb2312""?>
<int>10</int>"))
{
//声明序列化对象实例serializer
XmlSerializer serializer = new XmlSerializer(typeof(int));
//反序列化,并将反序列化结果值赋给变量i
int i = (int)serializer.Deserialize(rdr);
//输出反序列化结果
Console.WriteLine("i = " + i);
Console.Read();
}
}

以上代码用最简单的方式说明了xml序列化和反序列化的过程,.Net系统类库为我们做了大量的工作,序列化和反序列化都非常简单。但是在现实中业务需求往往比较复杂,不可能只简单的序列化一个int变量,显示中我们需要对复杂类型进行可控制的序列化。

[XmlRoot("cat")]
/
/要求不序列化Speed属性
[XmlIgnore]
[XmlAttribute]
[XmlElement]

可以使用XmlElement指定属性序列化为子节点(默认情况会序列化为子节点);或者使用XmlAttribute特性制定属性序列化为Xml节点的属性;还可以通过XmlIgnore特性修饰要求序列化程序不序列化修饰属性。

一、序列化对象

首先我们先定义实体类:

  public class People
{
//XmlAttribute:指定XmlSerializer将该类成员序列化为XML属性
[XmlAttribute]
public string Name { get; set; }
[XmlAttribute]
public int Age { get; set; }
} [XmlRoot]
public class Student : People
{
  
//定义SClass属性的序列化为Student节点的属性
[XmlElement]
public string SClass { get; set; }
[XmlElement]
public int Number { get; set; }
}

第一步:将实体类序列化为XML文档,代码如下:

    Student stu = new Student() { Age = 12, Number = 23, Name = "张三", SClass = "高一(2)班" };
    XmlSerializer ser = new XmlSerializer(typeof(Student));
    StringWriter writer = new StringWriter();
    ser.Serialize(writer,stu);
    MessageBox.Show(writer.ToString());

在弹出框,出现的结果是:

这样,我们就序列化成功了啊。。
第二步:现在我们来进行反序列化测试:

    //将Xml反序列为Student对象
    StringReader reader = new StringReader(writer.ToString());
    //Deserialize反序列化指定TextReader包含的Xml文档,当然,不仅仅可以是TextReader,还可以是Stream等等,具体看起构造函数参数即可知道
    Student stu2= (Student)ser.Deserialize(reader);

我们用上面得到XML数据进行反序列化测试。查看运行结果,ok的啦!

二、序列化列表
和上面一样,序列化学生列表(People类和Student类和上面代码一样)

    List<Student> stuList = new List<Student>();
    stuList.Add(new Student() { Age = 10, Number = 1, Name = "Tom", SClass = "Class One" });
    stuList.Add(new Student() { Age = 11, Number = 2, Name = "Jay", SClass = "Class Two" });
    stuList.Add(new Student() { Age = 12, Number = 3, Name = "Pet", SClass = "Class One" });
    stuList.Add(new Student() { Age = 13, Number = 4, Name = "May", SClass = "Class Three" });
   stuList.Add(new Student() { Age = 14, Number = 5, Name = "Soy", SClass = "Class Two" });      //序列化
    XmlSerializer ser = new XmlSerializer(typeof(List<Student>));
    StringWriter writer = new StringWriter();
    //将学生列表序列化为Xml数据
    ser.Serialize(writer, stuList);     //反序列化
    //要先将构造StringReader,作为Deserialize()的初始化参数
    StringReader reader = new StringReader(writer.ToString());
    //别忘了从Object到List<Student>,否则会报错。。
    List<Student> stuList2 = (List<Student>)ser.Deserialize(reader);

运行结果是(注意:根是ArrayOfStudent不是Student了):

三、序列化字典(键/值对)

在XmlSerializer中,不支持Dirctionary<>类型的对象,所以在序列化这种最常见类型的时候,只能按照它的格式先创建一个可以序列化的类型,然后,将数据存储在该可序列化的类型中,然后再进行序列化即可。

    Dictionary<string, int> dic = new Dictionary<string, int>();
   dic.Add("第一",1);
    dic.Add("第二", 2);
    dic.Add("第三", 3);
    dic.Add("第四", 4);     List<DictionaryList> dicList = new List<DictionaryList>();
    foreach (var a in dic)
    {
      DictionaryList dicl = new DictionaryList() { Name=a.Key, Value=a.Value};
      dicList.Add(dicl);     }
    //序列化
    XmlSerializer ser = new XmlSerializer(typeof(List<DictionaryList>));
    StringWriter writer = new StringWriter();
    //序列化为Xml数据
    ser.Serialize(writer, dicList);
    MessageBox.Show(writer.ToString());     //反序列化
    StringReader reader = new StringReader(writer.ToString());
    List<DictionaryList> stuList2 = (List<DictionaryList>)ser.Deserialize(reader);

运行结果是:

四、序列化图片

补充:XmlArray和XmlArrayItem的使用,用在数组中

先构造实体类:

    [XmlRoot("cats")]
public class CatCollection
{
[XmlArray("items"), XmlArrayItem("item")]
public Cat[] Cats { get; set; }
} //[XmlRoot("cat")] 加不加都无所谓的。
public class Cat
{
//定义Color属性的序列化为cat节点的属性
[XmlAttribute("color")]
public string Color { get; set; } //要求不序列化Speed属性
[XmlIgnore]
public int Speed { get; set; } //设置Saying属性序列化为Xml子元素
[XmlElement("saying")]
public string Saying { get; set; }
}

现在,进行序列化:

   //声明一个猫咪对象
   var cWhite = new Cat { Color = "White", Speed = 10, Saying = "White or black, so long as the cat can catch mice, it is a good cat" };
   var cBlack = new Cat { Color = "Black", Speed = 10, Saying = "White or black, so long as the cat can catch mice, it is a good cat" };    CatCollection cc = new CatCollection { Cats = new Cat[] { cWhite, cBlack } };    //序列化这个对象
   XmlSerializer serializer = new XmlSerializer(typeof(CatCollection));
   StringWriter writer = new StringWriter();
   serializer.Serialize(writer,cc);
   MessageBox.Show(writer.ToString());

运行结果是:

XmlSerializer内存泄漏问题:

多谢chenlulouis,仔细看了下msdn,确实存在泄漏的情况,msdn说明如下:

动态生成的程序集
为了提高性能,XML 序列化基础结构将动态生成程序集,以序列化和反序列化指定类型。此基础结构将查找并重复使用这些程序集。此行为仅在使用以下构造函数时发生:
XmlSerializer(Type)   XmlSerializer.XmlSerializer(Type, String)
如果使用任何其他构造函数,则会生成同一程序集的多个版本,且绝不会被卸载,这将导致内存泄漏和性能降低。最简单的解决方案是使用先前提到的两个构造函数的其中一个。否则,必须在 Hashtable 中缓存程序集,如以下示例中所示。

也就是说我们在使用XmlSerializer序列化,初始化XmlSerializer对象时最好使用下面两个构造函数否则会引起内存泄漏。

XmlSerializer(Type)  XmlSerializer.XmlSerializer(Type, String)

C#处理Xml的相关随笔:

补充:EncodeHelper类,只不过将上述我们序列化和反序列化进行封装而已,很容易理解
/// <summary>
/// 提供xml文档序列化 反序列化
/// </summary>
public sealed class EncodeHelper
{
/// <summary>
/// 反序列化XML字符串为指定类型
/// </summary>
public static object Deserialize(string Xml, Type ThisType)
{
XmlSerializer xmlSerializer = new XmlSerializer(ThisType);
object result;
try
{
using (StringReader stringReader = new StringReader(Xml))
{
result = xmlSerializer.Deserialize(stringReader);
}
}
catch (Exception innerException)
{
bool flag = false;
if (Xml != null)
{
if (Xml.StartsWith(Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble())))
{
flag = true;
}
}
throw new ApplicationException(string.Format("Couldn't parse XML: '{0}'; Contains BOM: {1}; Type: {2}.",
Xml, flag, ThisType.FullName), innerException);
}
return result;
} /// <summary>
/// 序列化object对象为XML字符串
/// </summary>
public static string Serialize(object ObjectToSerialize)
{
string result = null ;
try
{
XmlSerializer xmlSerializer = new XmlSerializer(ObjectToSerialize.GetType()); using (MemoryStream memoryStream = new MemoryStream())
{
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, new UTF8Encoding(false));
xmlTextWriter.Formatting = Formatting.Indented;
xmlSerializer.Serialize(xmlTextWriter, ObjectToSerialize);
xmlTextWriter.Flush();
xmlTextWriter.Close();
UTF8Encoding uTF8Encoding = new UTF8Encoding(false, true);
result= uTF8Encoding.GetString(memoryStream.ToArray());
}
}
catch (Exception innerException)
{
throw new ApplicationException("Couldn't Serialize Object:" + ObjectToSerialize.GetType().Name, innerException);
}
return result;
}
}

 

      http://hi.baidu.com/jackeyrain/item/79ad923564fa94f1e6bb7a11

     http://www.cnblogs.com/John-Connor/archive/2012/04/12/2440352.html

XML的序列化和反序列化 详细介绍的更多相关文章

  1. windows phone8.1:Xml,Json序列化和反序列化

    原文:windows phone8.1:Xml,Json序列化和反序列化 小梦本例主要实现以下四点内容: 将Car对象序列化为xml 将Car对象序列化为Json 将xml反序列化为Car对象 将js ...

  2. xml的序列化与反序列化求一个好用的东西,类似,newtonsoft.net转json的东西。xml里面的结构和数据库不一致..................

    xml的序列化与反序列化求一个好用的东西,类似,newtonsoft.net转json的东西.xml里面的结构和数据库不一致..................

  3. XML文件序列化和反序列化的相关内容

    问题缘由: XML反序列化出错,XML 文档(2, 2)中有错误,不应有 <configuration xmlns=''> 解决方法: 其实这个是很简单的,因为一般来说都是XML文档书写错 ...

  4. (转)C# Xml进行序列化与反序列化

    ---------------------------------------------------------------文章1---------------------------------- ...

  5. 通过XmlSerializer 实现XML的序列化与反序列化

    通过XmlSerializer 我们可以十分简单的将Model与XML进行转换 官文在点这里 帮助类 using System; using System.Text; using System.Xml ...

  6. XML的序列化与反序列化

    开发时会把数据持久化成xml格式,当然可以用xmlwriter来实现,不过感觉不方便,而且很繁琐.推荐使用直接序列化.反序列化对象的方法来处理. 直接上代码: public static class ...

  7. 几种常用的json序列化和反序列化工具介绍

    一.前言 Json序列化和反序列化工作中会时常用到,也是目前数据交互的常用格式,Rest风格的接口加上json格式的数据交互,真的是天作之合. 目前Json字符与Json对象的相互转换方式有很多,接下 ...

  8. C#XML的序列化与反序列化

    要序列化的对象的类: [Serializable]public class Person{private string name;public string Name{get{return name; ...

  9. C#实现复杂XML的序列化与反序列化

    已知.xml(再此命名default.xml)文件,请将其反序列化到一个实例对象. Default.XML文件如下: <?xml version="1.0" encoding ...

随机推荐

  1. 长方柱类【C++ 类定义】

    Description 编写基于对象的程序,求长方柱(Bulk)的体积.数据成员包括长(length).宽(width).高(heigth).体积,要求用成员函数实现下面的功能: (1)由键盘输入长方 ...

  2. HDU 1228 A + B 浙江大学研究生冠军

    Problem Description 读入两个小于100的正整数A和B,计算A+B. 须要注意的是:A和B的每一位数字由相应的英文单词给出.   Input 測试输入包括若干測试用例,每一个測试用例 ...

  3. PHP PDO sqlite ,Unable to Open database file的解决方法

    t.php在网站的根目录. fdy.db在inc文件夹下; t.php中sqlite路径写成相对路径 $db = new PDO('sqlite:inc/fdy.db'); 开始提示 Fatal er ...

  4. 导致Asp.Net站点重启的10个原因

    原文:导致Asp.Net站点重启的10个原因 Asp.Net站点有时候会莫名其妙的重启,什么原因导致的却不得而知,经过一番折腾后,我总结了导致Asp.Net站点重启的10个原因 1. 回收应用程序池会 ...

  5. 基于高性能的硬件配置Nginx

    Nginx高级配置将涉及硬件,假设你配置不好,直接使各种性能下降. 我这里总结一下.怎样依据server的硬件设备来配置Nginx. 见下图: 低訪问量的网络,能够这样配置. 标准的网络訪问量,能够这 ...

  6. 【Cocos2d-x】Mac 在 Cocos2d-x 3.X 打包Android

    今天cocos2d-x 3.0正式版最终公布了,下午特地下载了来尝尝鲜,废话不多说了. 3.0正式版的环境搭建和之前的RC版事实上是一样的,太多的教程也写了怎样搭建.今天来写写我自己是怎样来搭建的. ...

  7. Socket方法LAN多线程文件传输

    1.思维:为了实现各种文件的大小可以被发送和接收的,它可以被设置为发送和接收缓冲器环.并记录文件的位置读取,假设读入缓冲区的字节的特定数目大于缓冲区的大小较小.然后该文件被发送,退出发送周期,关闭连接 ...

  8. jxl创Excel档java示例代码说明

    记得下载 并 导入jxl.jar 包,免积分下载地址:http://download.csdn.net/detail/u010011052/7561041 package Test; import j ...

  9. Android开发学习总结(五)——Android应用目录结构分析(转)

    一.手动创建android项目 手动创建一个Android项目,命名为HelloWorld,命令如下: android create project -n HelloWorld -t 1 -p E:/ ...

  10. js 自己容易搞混的笔记查询

    相似的操作 var str2 = "0123456789"; console.log(str2.slice(4,7)); //------------"456" ...