0
点赞
收藏
分享

微信扫一扫

Winform中实现序列化指定类型的对象到指定的Xml文件和从指定的Xml文件中反序列化指定类型的对象

小云晓云 2023-02-15 阅读 80


场景

在Winform程序中需要将某些页面的设置存储到配置文件中,下次再次打开时通过配置文件读取,点击确定时能将将设置保存到配置文件中。

之前介绍过

Winform中自定义xml配置文件后对节点进行读取与写入:


下面是用System.Xml.Serialization实现的方式

注:

实现

首先新建一个实体类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配置文件的全路径

 

 

举报

相关推荐

0 条评论