0
点赞
收藏
分享

微信扫一扫

Winform中实现保存配置到文件/项目启动时从文件中读取配置(序列化与反序列化对象)


场景

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


上面讲的序列化对象的流程需要进行补充。

Winform程序需要将某些动态配置的TextBox的内容在配置后进行保存,下次启动时仍然读取加载显示之前的配置。

注:

实现

1、新建配置项对象类,属性根据要保存的内容对应而定。

[Serializable]
public class DataConfig
{

/// <summary>
/// 煤矿编码
/// </summary>
public string MineCode { get; set; }

/// <summary>
/// 煤业公司编码
/// </summary>
public string CompanyCode { get; set; }

/// <summary>
/// http地址
/// </summary>
public string HttpAddress { get; set; }

/// <summary>
/// MqttIp
/// </summary>
public string MqttIp { get; set; }

/// <summary>
/// MqttPort
/// </summary>
public string MqttPort { get; set; }

/// <summary>
/// MqttUsername
/// </summary>
public string MqttUsername { get; set; }

/// <summary>
/// MqttPassword
/// </summary>
public string MqttPassword { get; set; }
}

注意要在类上添加

[Serializable]

2、然后新建序列化对象的工具类SerializeXmlHelper

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace DataConvert.dataconvert
{
class SerializeXmlHelper
{
/// <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, Encoding.UTF8);
}
catch (Exception ex)
{
Console.Write(ex);
}
}
}

/// <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;
}
}

/// <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, Encoding.UTF8);
T obj = DeserializeObject<T>(xmlContent);
return obj;
}
}
catch (Exception ex)
{
Console.Write(ex);
return default(T);
}
}
}

/// <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);
}
}
/// <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 (!File.Exists(path))
{
FileStream fileStream = File.Create(path);
fileStream.Close();
}
lock (obj)
{
using (StreamWriter streamWriter = new StreamWriter(path, false, encoding))
{
streamWriter.WriteLine(content);
streamWriter.Close();
streamWriter.Dispose();
}
}
}
catch (Exception ex)
{
Console.Write(ex);

}
}
}
}

部分方法中用到了文件操作的相关工具类方法,所以新建文件操作工具类FileHelper

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DataConvert.com.bdtd.dataconvert
{
class FileHelper
{
/// <summary>
/// 向指定文件写入内容
/// </summary>
/// <param name="path">要写入内容的文件完整路径</param>
/// <param name="content">要写入的内容</param>
public static void WriteFile(string path, string content)
{
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, System.Text.Encoding.Default))
{
streamWriter.WriteLine(content);
streamWriter.Close();
streamWriter.Dispose();
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}

/// <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 (Exception ex)
{
Console.WriteLine(ex.Message);
}
}

/// <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;
}

}
}

3、序列化对象到文件

这里可以在按钮的点击事件或者窗体的closing事件中获取到各textBox的内容并序列化到xml文件中

private void button_save_config_Click(object sender, EventArgs e)
{
//保存配置到文件
try {
saveConfigToFile();
MessageBox.Show("配置保存成功");
} catch (Exception ex) {
MessageBox.Show("配置保存失败:"+ex.Message);
}
}

具体执行的方法

private void saveConfigToFile() {
try {
DataConfig dataConfig = new DataConfig();
dataConfig.MineCode = textBox_mine_code.Text.Trim();
dataConfig.CompanyCode = textBox_company_code.Text.Trim();
dataConfig.HttpAddress = textBox_origin_address.Text.Trim();
dataConfig.MqttIp = textBox_target_address.Text.Trim();
dataConfig.MqttPort = textBox_mqtt_port.Text.Trim();
dataConfig.MqttUsername = textBox_mqtt_username.Text.Trim();
dataConfig.MqttPassword = textBox_mqtt_password.Text.Trim();
string path = configFilePath;
SerializeXmlHelper.SerializeXml(dataConfig, path);
} catch(Exception ex) {
textBox_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":保存配置到文件失败:" + ex.Message);
textBox_log.AppendText("\r\n");
}
}

前面都是获取textBox中的输入内容,后面两行才是进行序列化对象的实现。

文件的路径提前声明变量

//配置文件存放路径
private string configFilePath = Application.StartupPath + "\\config\\config.xml";

这里将配置文件放在启动目录下的config下的config.xml中

4、反序列化配置文件到对象

可以在窗体的load时间中读取配置文件并反序列化到对象,然后给各控件赋值。

private void Form1_Load(object sender, EventArgs e)
{
//从配置文件读取配置
readConfigFromFile();
}

实现方法

//从配置文件读取配置
private void readConfigFromFile()
{
try {
DataConfig dataConfig = new DataConfig();
string path = configFilePath;
if (File.Exists(path)) {
dataConfig = SerializeXmlHelper.DeserializeXml<DataConfig>(path);
textBox_mine_code.Text = dataConfig.MineCode;
textBox_company_code.Text = dataConfig.CompanyCode;
textBox_origin_address.Text = dataConfig.HttpAddress;
textBox_target_address.Text = dataConfig.MqttIp;
textBox_mqtt_port.Text = dataConfig.MqttPort;
textBox_mqtt_username.Text = dataConfig.MqttUsername;
textBox_mqtt_password.Text = dataConfig.MqttPassword;
}
} catch(Exception ex) {
textBox_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":从配置文件读取配置失败:" + ex.Message);
textBox_log.AppendText("\r\n");
}
}

注意这里要规避首次加载没有配置文件或者人为删除配置文件的情况,需要加判断。

其次上面在新建xml文件中,也对config路径做了判断,如果不存在则创建。

举报

相关推荐

0 条评论