场景
在Winform程序中需要将某些页面的设置存储到配置文件中,下次再次打开时通过配置文件读取,点击确定时能将将设置保存到配置文件中。
之前介绍过
Winform中自定义xml配置文件后对节点进行读取与写入:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/100532137
下面是用System.Xml.Serialization实现的方式
注:
博客主页:
https://blog.csdn.net/badao_liumang_qizhi
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载
实现
首先新建一个实体类DataItem,并标识可以序列化
[Serializable] public class DataItem { public DataItem() { this.DisplayIndex = -1; } /// <summary> /// 项索引 /// </summary> public int ItemIndex { get; set; } /// <summary> /// 关联的数据属性 /// </summary> public string DataPropertyName { get; set; } /// <summary> /// 显示的名称 /// </summary> public string DisplayName { get; set; } /// <summary> /// 显示宽度(列宽) /// </summary> public int DisplayWidth { get; set; } /// <summary> /// 显示精度(小数位数) /// </summary> public int DisplayPrecision { get; set; } /// <summary> /// 是否显示 /// </summary> public bool IsDisplay { get; set; } /// <summary> /// 是否按空值显示 /// </summary> public bool IsDisplayNullValue { get; set; } /// <summary> /// 显示位置索引 /// </summary> public int DisplayIndex { get; set; } /// <summary> /// 是否导出 /// </summary> public bool NeedExport = true; }
实现将对象序列化为xml文件
首先获取上面DataItem的list,以及要保存的文件路径
然后新建一个工具类方法,实现对象序列化
/// <summary> /// 序列化指定类型的对象到指定的Xml文件 /// </summary> /// <typeparam name="T">要序列化的对象类型</typeparam> /// <param name="obj">要序列化的对象</param> /// <param name="xmlFileName">保存对象数据的完整文件名</param> public static void SerializeXml<T>(T obj, string xmlFileName) { lock (xmlFileName) { try { string dir = Path.GetDirectoryName(xmlFileName); //获取文件路径 if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } string xmlContent = SerializeObject<T>(obj); FileHelper.WriteFile(xmlFileName, xmlContent, System.Text.Encoding.UTF8); } catch (Exception ex) { Console.Write(ex); } } }
在此工具类方法中调用了SerializeObject将对象序列化为xml对象的方法
/// <summary> /// 把对象序列化为xml字符串 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="obj"></param> /// <returns></returns> public static string SerializeObject<T>(T obj) { if (obj != null) { StringWriter strWriter = new StringWriter(); XmlSerializer serializer = new XmlSerializer(typeof(T)); serializer.Serialize(strWriter, obj); return strWriter.ToString(); } else { return String.Empty; } }
在此工具类方法中还调用了文件工具类的一个方法WriteFile
/// <summary> /// 向指定文件写入内容 /// </summary> /// <param name="path">要写入内容的文件完整路径</param> /// <param name="content">要写入的内容</param> /// <param name="encoding">编码格式</param> public static void WriteFile(string path, string content, System.Text.Encoding encoding) { try { object obj = new object(); if (!System.IO.File.Exists(path)) { System.IO.FileStream fileStream = System.IO.File.Create(path); fileStream.Close(); } lock (obj) { using (System.IO.StreamWriter streamWriter = new System.IO.StreamWriter(path, false, encoding)) { streamWriter.WriteLine(content); streamWriter.Close(); streamWriter.Dispose(); } } } catch (System.Exception ex) { Console.Write(ex); } }
然后调用工具类方法SerializeXml并传递要序列化的对象的list和要序列化的文件的路径
文件路径要传递类似于以下这种
D:MainTestinDebugDataViewerConfigadao.xml
序列化调用示例
SerializeXml<List<DataItem>>(_recordDataItems, this.filepathRecord);
其中第一个参数是DataItem的list,第二个参数是序列化的文件路径
序列化之后的文件示例:
<?xml version="1.0" encoding="utf-16"?> <ArrayOfDataItem xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <DataItem> <NeedExport>true</NeedExport> <ItemIndex>0</ItemIndex> <DataPropertyName>DataPoint</DataPropertyName> <DisplayName>记录序号</DisplayName> <DisplayWidth>9</DisplayWidth> <DisplayPrecision>0</DisplayPrecision> <IsDisplay>true</IsDisplay> <IsDisplayNullValue>false</IsDisplayNullValue> <DisplayIndex>0</DisplayIndex> </DataItem> <DataItem> <NeedExport>true</NeedExport> <ItemIndex>1</ItemIndex> <DataPropertyName>RecordTime</DataPropertyName> <DisplayName>记录时间</DisplayName> <DisplayWidth>9</DisplayWidth> <DisplayPrecision>0</DisplayPrecision> <IsDisplay>true</IsDisplay> <IsDisplayNullValue>false</IsDisplayNullValue> <DisplayIndex>1</DisplayIndex> </DataItem> </ArrayOfDataItem>
将XML反序列化为对象
同上在工具类中新建工具类方法DeserializeXml
/// <summary> /// 从指定的Xml文件中反序列化指定类型的对象 /// </summary> /// <typeparam name="T">反序列化的对象类型</typeparam> /// <param name="xmlFileName">保存对象数据的文件名</param> /// <returns>返回反序列化出的对象实例</returns> public static T DeserializeXml<T>(string xmlFileName) { lock (xmlFileName) { try { if (!File.Exists(xmlFileName)) { Console.Write("序列化文件不存在!"); return default(T); } else { string xmlContent = FileHelper.ReadFile(xmlFileName, System.Text.Encoding.UTF8); T obj = DeserializeObject<T>(xmlContent); return obj; } } catch (Exception ex) { Console.Write(ex); return default(T); } } }
然后在此工具类方法中调用了DeserializeObject把xml字符串反序列化为对象的方法
/// <summary> /// 把xml字符串反序列化为对象 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="xmlString"></param> /// <returns></returns> public static T DeserializeObject<T>(string xmlString) { if (!String.IsNullOrEmpty(xmlString)) { StringReader strReader = new StringReader(xmlString); XmlSerializer serializer = new XmlSerializer(typeof(T)); T obj = (T)serializer.Deserialize(strReader); return obj; } else { return default(T); } }
以及读取文件的方法ReadFile
/// <summary> /// 读取文件内容 /// </summary> /// <param name="path">要读取的文件路径</param> /// <param name="encoding">编码格式</param> /// <returns>返回文件内容</returns> public static string ReadFile(string path, System.Text.Encoding encoding) { string result; if (!System.IO.File.Exists(path)) { result = "不存在相应的目录"; } else { System.IO.FileStream stream = new System.IO.FileStream(path, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite); System.IO.StreamReader streamReader = new System.IO.StreamReader(stream, encoding); result = streamReader.ReadToEnd(); streamReader.Close(); streamReader.Dispose(); } return result; }
调用方法示例
recordDataItems =DeserializeXml<List<DataItem>>(this.filepathRecord);
其中返回值接受是使用的List<DataItem>参数传值的是xml配置文件的全路径