一、前言
何为序列化?何为反序列化?
XML 序列化是将对象的公共属性 (Property) 和字段转换为序列格式(这里是指 XML)以便存储或传输的过程。序列化的时候,一般要传入流以及类作为参数,若该流为写入流,则会写进文件里。
反序列化则是从 XML 输出中重新创建原始状态的对象。因此,可以将序列化视为将对象的状态保存到流或缓冲区的方法。反序列化的时候,一般要传入流作为参数,若该流为读取流,则会读取文件。
二、代码介绍
代码主要有两个模块组成:
1.XmlSerialization:执行序列化和反序列化的类
2.serializeXML:需要序列化的对象格式,决定了生成XML格式的。
三、XmlSerialization类
SerializeObjectToFile(object obj, string path)将对象序列化
/// <summary>
/// 将对象按XML序列化后写入到一个文件
/// </summary>
/// <param name="obj">要序列化的对象</param>
/// <param name="path">保存文件路径</param>
/// <returns>执行结果</returns>
public static bool SerializeObjectToFile(object obj, string path)
{
try
{
if (!string.IsNullOrEmpty(path))
{
//如果目录不存在,则创建相应目录
string DirPath = Path.GetDirectoryName(path);
if ((!string.IsNullOrWhiteSpace(DirPath)) && (!Directory.Exists(DirPath)))
{
Directory.CreateDirectory(DirPath);
}
//序列化对象
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.NewLineChars = "\r\n";
settings.Encoding = Encoding.UTF8;
settings.IndentChars = " ";
///
//去掉要结点的 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 属性
XmlSerializerNamespaces _namespaces = new XmlSerializerNamespaces(
new XmlQualifiedName[] {
new XmlQualifiedName(string.Empty, "aa")
});
//
using (XmlWriter xw = XmlWriter.Create(path, settings))
{
var xs = new XmlSerializer(obj.GetType());
//xs.Serialize(xw, obj, new XmlSerializerNamespaces());
xs.Serialize(xw, obj, _namespaces);
xw.Close();
}
return true;
}
}
catch (Exception)
{
}
return false;
}
DeserializeObjectFromFile(string path)将对象反序列化
/// <summary>
/// 从文件中反序列化对象
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="path">文件路径</param>
/// <returns>反序列化得到的对象</returns>
public static T DeserializeObjectFromFile<T>(string path)
{
try
{
//参数校验
if (string.IsNullOrEmpty(path))
{
return default(T);
}
//读取文件
string xmlString = File.ReadAllText(path);
XmlSerializer mySerializer = new XmlSerializer(typeof(T));
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(xmlString)))
{
using (StreamReader sr = new StreamReader(ms, Encoding.UTF8))
{
return (T)mySerializer.Deserialize(sr);
}
}
}
catch (Exception)
{
}
return default(T);
}
三、serializeXML序列化对象的格式
[Serializable]//打上这个标签,会对该类进行序列化
[XmlRoot(“TestConfig”)]设定根目录的名称,紧接着要创建同样的类名
[XmlAttribute(“Config_Name”)]//XML创建时,生成当前类的属性
[XmlArray(“AllTestItem”), XmlArrayItem(“TestItem”)]建立根目录下的子节点以及其下一级节点
public List AllTestItem为了建立TestItem的多个实例化队列
/// <summary>
/// 这是一个测试配置的类
/// </summary>
[Serializable]//打上这个标签,会对该类进行序列化
[XmlRoot("TestConfig")]
public class TestConfig
{
[XmlAttribute("Config_Name")]//XML创建时,生成当前类的属性,不注明()里面的内容就会 直接用变量名
public string Config_Name;
[XmlArray("AllTestItem"), XmlArrayItem("TestItem")]在 XML 中生成父子关联节点。不写这个就是按照原数组名称与数组类型名生成对应节点TestItem与CellOverallTestItem
public List<TestItem> AllTestItem;
}
/// <summary>
/// 这是一个关于测试项目的类
/// </summary>
[Serializable]//打上这个标签,会对该类进行序列化
public class TestItem
{
[XmlElement("userId")]
public int userId;
private string m_UserName;
[XmlElement("userName")]
public string UserName
{
get { return m_UserName; }
set { m_UserName = value; }
}
[XmlAttribute("Step")]//XML创建时,生成当前类的属性,不注明()里面的内容就会 直接用变量名
public int Step;
[XmlAttribute("Name")]//XML创建时,生成当前类的属性,不注明()里面的内容就会 直接用变量名
public string Name;
[XmlAttribute("X")]//XML创建时,生成当前类的属性,不注明()里面的内容就会 直接用变量名
public double X;
[XmlAttribute("Y")]//XML创建时,生成当前类的属性,不注明()里面的内容就会 直接用变量名
public double Y;
[XmlAttribute("Z")]//XML创建时,生成当前类的属性,不注明()里面的内容就会 直接用变量名
public double Z;
[XmlAttribute("Roll")]//XML创建时,生成当前类的属性,不注明()里面的内容就会 直接用变量名
public double Roll;
[XmlAttribute("default1")]//XML创建时,生成当前类的属性,不注明()里面的内容就会 直接用变量名
public string default1;
[XmlAttribute("default2")]//XML创建时,生成当前类的属性,不注明()里面的内容就会 直接用变量名
public string default2;
//[XmlIgnore]//序列化中忽略掉
//public String kkk;
}
三、主程序调用方法演示
下面以序列化为例,展示实际效果
TestConfig My_TestConfig = new TestConfig(); //新建一个TestConfig对象
My_TestConfig.Config_Name = "配置文件";
TestItem My_TestItem = new TestItem(); //新建一个TestItem对象
My_TestItem.userId = 12222;
My_TestItem.UserName = "asc";
My_TestItem.Step = 1;
My_TestItem.Name = "abc";
My_TestItem.X = 11.2;
My_TestItem.Y = 22.1;
My_TestItem.Z = 20.1;
My_TestItem.Roll = 34.1;
My_TestItem.default1 = "11";
My_TestItem.default2 = "22";
TestItem My_TestItem1 = new TestItem();
My_TestItem1.userId = 11;
My_TestItem1.UserName = "hhh";
My_TestItem1.Step = 1;
My_TestItem1.Name = "abc";
My_TestItem1.X = 11.2;
My_TestItem1.Y = 22.1;
My_TestItem1.Z = 20.1;
My_TestItem1.Roll = 34.1;
My_TestItem1.default1 = "11";
My_TestItem1.default2 = "22";
My_TestConfig.AllTestItem = new List<TestItem>();//实例化List
My_TestConfig.AllTestItem.Add(My_TestItem);//添加
My_TestConfig.AllTestItem.Add(My_TestItem1);
XmlSerialization.SerializeObjectToFile(My_TestConfig, path); //将对象实例化
}
实际效果如下
<?xml version="1.0" encoding="utf-8"?>
<TestConfig Config_Name="配置文件">
<AllTestItem>
<TestItem Step="1" Name="abc" X="11.2" Y="22.1" Z="20.1" Roll="34.1" default1="11" default2="22">
<userId>12222</userId>
<userName>asc</userName>
</TestItem>
<TestItem Step="1" Name="abc" X="11.2" Y="22.1" Z="20.1" Roll="34.1" default1="11" default2="22">
<userId>11</userId>
<userName>hhh</userName>
</TestItem>
</AllTestItem>
</TestConfig>
四、主程序调用方法演示
测试源码见下方链接
链接: 序列化与反序列化测试源代码