场景
在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:\Main\Test\bin\Debug\Data\Viewer\Config\badao.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配置文件的全路径