转载:
http://dearymz.blog.163.com/blog/static/20565742006423122240/?suggestedreading&wumii
Xml序列化
Xml文件格式是一种非常有用的格式,在跨平台方面做的异常出色。实际中常使用Xml文件作为配置文件或者是数据的存贮文件。采用Xml文件绝对比简单的txt或者ini文件更有效,也绝对比采用注册表格让人喜欢。 单个对象的序列化需要实现[Serializable]特性。需要一个无参的构造函数,并且不对外部无法访问的数据进行操作,比如私有的数据成员。通常不提倡将本应私有的数据成员(字段)设置为公有,这样做破坏了数据的封装性,带来潜在的安全隐患。一般要给需要的序列化的成员实现公有的get和set属性,这样数据可从外部安全的访问,也可正常的进行序列化。 实际中通常还使用的是ArrayList对象的序列化。这样可以在一次的序列化过程中处理很多的工作,而且在反序列化后不失对象之间的结构关系。 下面我们开始演练Xml格式的序列化。 这里的测试对象如下所示: /// <summary> /// 要进行序列化的测试类 /// </summary> [Serializable] public class Test { private string m_ID; private string m_Name; public string ID { get{return m_ID;} set{m_ID = value;} } public string Name { get{return m_Name;} set{m_Name = value;} } public override string ToString() { return m_ID + "t" + m_Name; } public Test() : this("","") { } public Test(string id,string name) { m_ID = id; m_Name = name; } public void Show() { Console.WriteLine(this.ToString()); } } 添加了XmlSerializeTools实用工具类来辅助进行Xml的操作: using System; using System.Collections; using System.Xml; using System.Xml.Serialization;
namespace ymz { /// <summary> /// Xml序列化和反序列化的实用工具 /// </summary> public class XmlSerializeTools {
/// <summary> /// 执行单个对象的序列化 /// </summary> /// <param name="fileName">序列化的目标文件路径名</param> /// <param name="data">要序列化的对象</param> /// <param name="type">要序列化的对象类型(可以通过typeof(*)的格式获取)</param> public static void XmlSerializeObject(string fileName,object data,Type type) { XmlTextWriter xtw = new XmlTextWriter(fileName,System.Text.Encoding.UTF8); XmlSerializer xs = new XmlSerializer(type); xs.Serialize(xtw,data); xtw.Close(); }
/// <summary> /// 执行单个对象的反序列化 /// </summary> /// <param name="fileName">反序列化的原文件路径名</param> /// <param name="type">要反序列化的对象类型(可以通过typeof(*)的格式获取)</param> /// <returns>反序列化后的对象</returns> public static Object XmlDeserializeObject(string fileName,Type type) { XmlSerializer xolds = new XmlSerializer(type); XmlTextReader xt = new XmlTextReader(fileName); object data = xolds.Deserialize(xt); xt.Close(); return data; }
/// <summary> /// ArrayList的序列化 /// </summary> /// <param name="fileName">序列化的目标文件路径名</param> /// <param name="arrayList">要序列化的ArrayList对象</param> public static void XmlSerializeArrayList(string fileName,ArrayList arrayList) { XmlSerializer xs = new XmlSerializer(typeof(ArrayList)); __XmlSerializeArrayList(fileName,arrayList,xs); }
/// <summary> /// ArrayList的序列化 /// </summary> /// <param name="fileName">序列化的目标文件路径名</param> /// <param name="arrayList">要序列化的ArrayList对象</param> /// <param name="extraTypes">ArrayList中对象类型信息 /// (当ArrayList中为复杂类型时需提供该参数。可以通过"new Type[]{*,*}"格式提供)</param> public static void XmlSerializeArrayList(string fileName,ArrayList arrayList, Type[] extraTypes) { XmlSerializer xs = new XmlSerializer(typeof(ArrayList),extraTypes); __XmlSerializeArrayList(fileName,xs); } private static void __XmlSerializeArrayList(string fileName,ArrayList arrayList ,XmlSerializer xs) { XmlTextWriter xtw = new XmlTextWriter(fileName,System.Text.Encoding.UTF8); xs.Serialize(xtw,arrayList); xtw.Close(); } /// <summary> /// ArrayList的反序列化 /// </summary> /// <param name="fileName">反序列化的原文件路径名</param> /// <returns>反序列化后的ArrayList对象</returns> public static ArrayList XmlDeserializeArrayList(string fileName) { XmlSerializer xolds = new XmlSerializer(typeof(ArrayList)); return __XmlDeserializeArrayList(fileName,xolds); } /// <summary> /// ArrayList的反序列化 /// </summary> /// <param name="fileName">反序列化的原文件路径名</param> /// <param name="extraTypes">ArrayList中对象类型信息 /// (当ArrayList中为复杂类型时需提供该参数。可以通过"new Type[]{*,*}"格式提供)</param> /// <returns>反序列化后的ArrayList对象</returns> public static ArrayList XmlDeserializeArrayList(string fileName,Type[] extraTypes) { XmlSerializer xolds = new XmlSerializer(typeof(ArrayList),extraTypes); return __XmlDeserializeArrayList(fileName,xolds); } private static ArrayList __XmlDeserializeArrayList(string fileName,XmlSerializer xolds) { XmlTextReader xt = new XmlTextReader(fileName); ArrayList list = (ArrayList)xolds.Deserialize(xt); xt.Close(); return list; } } } 简单类型的ArrayList比如ArrayList<int>之类的,可以直接调用函数XmlSerializeArrayList和XmlDeserializeArrayList函数的二参数版本处理,系统会自动默认的提供相应的类型信息。但是如果要实现复杂类型,比如自定义的结构体或者类时,需要明确的指出对象的类型信息。这时需要采用XmlSerializeArrayList和XmlDeserializeArrayList函数的三参数版本。 下面是我的测试函数: static void Main(string[] args) { string pathBase = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + ""; Test t1 = new Test("dearymz@163.com","秒大刀"); t1.Show();
ymz.XmlSerializeTools.XmlSerializeObject(pathBase + "object.xml",t1,typeof(Test)); Test t2 = (Test)ymz.XmlSerializeTools.XmlDeserializeObject(pathBase + "object.xml",typeof(Test)); t2.Show();
ArrayList a1 = new ArrayList(); a1.Add(t1); a1.Add(t2); foreach(Test t in a1) { t.Show(); } ymz.XmlSerializeTools.XmlSerializeArrayList(pathBase + "ArrayList.xml",a1,new Type[]{typeof(Test)}); //下面方法抛出“未处理的异常: System.InvalidOperationException: 生成 XML 文档时出错。”异常 //ymz.XmlSerializeTools.XmlSerializeArrayList(pathBase + "ArrayList.xml",a1); ArrayList a2 = ymz.XmlSerializeTools.XmlDeserializeArrayList(pathBase + "ArrayList.xml",new Type[]{typeof(Test)}); //下面方法抛出“未处理的异常: System.InvalidCastException: 指定的转换无效。”异常 //ArrayList a2 = ymz.XmlSerializeTools.XmlDeserializeArrayList(pathBase + "ArrayList.xml"); foreach(Test t in a2) { t.Show(); } } 结论: 对于复杂类型集合的序列化操作时一定要明确指出其类型信息。 (由于页面空间的限制,这里略去了所有的代码格式和颜色信息) (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|