Winform中实现保存配置到文件/项目启动时从文件中读取配置(序列化与反序列化对象)
场景
Winform中实现序列化指定类型的对象到指定的Xml文件和从指定的Xml文件中反序列化指定类型的对象:
Winform中实现序列化指定类型的对象到指定的Xml文件和从指定的Xml文件中反序列化指定类型的对象_winform xml序列化_霸道流氓气质的博客-CSDN博客
上面讲的序列化对象的流程需要进行补充。
Winform程序需要将某些动态配置的TextBox的内容在配置后进行保存,下次启动时仍然读取加载显示之前的配置。
注:
博客:
霸道流氓气质的博客_CSDN博客-C#,架构之路,SpringBoot领域博主
实现
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路径做了判断,如果不存在则创建。
相关文章:
Winform中实现保存配置到文件/项目启动时从文件中读取配置(序列化与反序列化对象)
场景 Winform中实现序列化指定类型的对象到指定的Xml文件和从指定的Xml文件中反序列化指定类型的对象: Winform中实现序列化指定类型的对象到指定的Xml文件和从指定的Xml文件中反序列化指定类型的对象_winform xml序列化_霸道流氓气质的博客-CSDN博客 上面讲的序…...
基于python的超市历年数据可视化分析
人生苦短 我用python Python其他实用资料:点击此处跳转文末名片获取 数据可视化分析目录人生苦短 我用python一、数据描述1、数据概览二、数据预处理0、导入包和数据1、列名重命名2、提取数据中时间,方便后续分析绘图三、数据可视化1、美国各个地区销售额的分布&…...
GPT-4技术报告
摘要 链接:https://cdn.openai.com/papers/gpt-4.pdf 我们汇报了GPT-4的发展,这是一个大规模的多模态模型,可以接受图像和文本输入并产生文本输出。虽然在许多现实场景中,GPT-4的能力不如人类,但它在各种专业和学术基…...
前端性能优化
总结 使用打包工具对代码进行打包压缩;引入css时采用link标签,并放入头部,使其与文档一起加载,减少页面卡顿时间;尽量减少dom结构的重排和重绘;使用css雪碧图,减少网络请求;对不同分…...
尚医通-(三十三)就诊人管理功能实现
目录: (1)前台用户系统-就诊人管理-需求说明 (2)就诊人管理-接口开发-列表接口 (3)就诊人管理-接口开发-其他接口 (4)前台用户系统-就诊人管理-前端整合 ࿰…...
《Spring Boot 趣味实战课》读书笔记(二)
牛刀小试——五分钟入门 Spring Boot 万物皆可 Hello World 创建一个 Web 工程 填写项目信息 选择依赖 从 IDEA 打开下载好的 Spring Boot 工程: 完成核心代码 创建 HelloController 类并编写 hello 方法 创建一个 HelloController 类,或者选择 Fi…...
Spring Cloud -- GateWay
为什么需要网关在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢?如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去调用。这样的话会产生很多问题,例…...
【C语言】memcpy , memset等内存操作函数使用方法与注意事项
这个章节,我们探讨C语言内存操作函数。 重点介绍处理内存操作函数使用和注意事项 和内存函数如何模拟实现。 内存函数所需头文件 #include<string.h> 文章目录memcpymemcpy 函数模拟实现memmovememmove 函数模拟实现memcmpmemcmp 函数模拟实现memsetmemset 函…...
尚融宝04-mybatis-plus插件和条件构造器
目录 一、分页插件 1、添加配置类 2、添加分页插件 3、测试分页 二、XML自定义分页 1、UserMapper中定义接口方法 2、定义XML 3、测试 三、乐观锁 1、场景 2、乐观锁方案 3、乐观锁实现流程 4、优化流程 四、wapper介绍 1、Wrapper家族 2、创建测试类 五、Qu…...
面试重难点问题(C++)
持续更新!!!!! 网络部分 1.问,四次挥手的过程,和双方状态变化? 挥手这前,两边都是established状态,客户端发起断开请求,向服务器发送fin请求&…...
androidx.appcompat 升级到1.5.1 趟过的坑
APP 要上google play,Android SDK 版本要升级到32;接了一个第三方SDK,不巧的是这个SDK引用appcompat是1.5.1,顺手把appcompat 包升级到1.5.1,这草率的一升,带来的不止一地鸡毛,还有精神上被残忍…...
[C++]反向迭代器
目录 前言: 1 对反向迭代器的构造思想 2 实现反向迭代器 3 完整代码 前言: 本篇文章主要介绍了STL容器当中的反向迭代器,可能有朋友会说:“反向迭代器有什么好学的?不一样还是迭代器吗,我正向能写出来&…...
解析Python编程中的包结构
假设你想设计一个模块集(也就是一个“包”)来统一处理声音文件和声音数据。通常由它们的扩展有不同的声音格式,例如:WAV,AIFF,AU),所以你可能需要创建和维护一个不断增长的各种文件格…...
【前端】深入浅出缓存原理
缓存的基本原理 对于前端来说,缓存主要分为浏览器缓存(比如 localStorage、sessionStorage、cookie等等)以及http缓存,也是本文主要讲述的。 当然叫法也不一样,比如客户端缓存大概包括浏览器缓存和http缓存 所谓htt…...
单调栈图文详解(附Java模板)
🍏🍐🍊🍑🍒🍓🫐🥑🍋🍉🥝 啥是"单调栈",它能解决什么样的问题? 文章目录🦩单调栈的概念&a…...
彻底理解Session、Cookie、Token,入门及实战
文章目录Session Cookie的使用Token的使用Session Cookie的使用 1. Session存储数据 HttpSession session request.getSession(); //Servlet底层通过的SESSIONID,获取Session对象。 session.setAttribute("loginTime",new Date()); out.println(&q…...
为什么运营商大数据可以精准获客?
“获客难”,“获客成本高”,一直是困扰企业的大问题,身边的许多朋友在吐槽客户的意向度不高,总是无法成交,员工非常积极主动去跟踪客户了,但始终事倍功半,这就像是老人们常说的一句老话“热脸贴…...
【数据结构】栈的实现
💯💯💯 本篇主要利用数组来实现栈,对于栈的各种操作都作详细介绍,压栈,出栈以及获取栈中元素的操作都是学习栈的必备知识,快来学起来吧!!!©Ⅰ.栈的概念及…...
【链表OJ题(六)】链表分割
📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:数据结构 🎯长路漫漫浩浩,万事皆有期待 文章目录链表OJ题(六)1. 链表…...
C++类中的三大函数(构造,析构,拷贝)
下面一段话与大家共勉:每个人的一生都会遇到很多边界,有些边界可以突破,有些则不能。那些无法突破的边界就是你的极限,而划分边界的标准就是“阈值”。每次突破阈值之后,人生轨迹就会发生剧烈变化,其间需要…...
从Simulink到Tina:硬件工程师如何更“接地气”地获取电路传递函数?
从Simulink到Tina:硬件工程师如何更“接地气”地获取电路传递函数? 在系统级仿真与PCB调试的鸿沟之间,硬件工程师常常面临一个尴尬的现实:Simulink的数值解虽然精确,却像黑箱般难以直接指导电路板上电阻电容的调整。当…...
告别手动提交!用Bash脚本批量处理VASP+ShengBTE热输运计算的700+任务
计算材料学自动化革命:Bash脚本驱动的高通量热输运计算实践 在计算材料学领域,研究者常常需要处理数百甚至上千个相似的计算任务。以硅材料热输运性质计算为例,当使用VASP结合ShengBTE进行三阶力常数计算时,可能产生700多个独立的…...
全志V853开发板驱动7寸RGB屏:Linux DRM设备树配置与调试实战
1. 项目概述:当开发板遇上七寸RGB屏最近在折腾百问网的100ASK_V853-PRO开发板,发现一个挺有意思的需求:让它驱动一块七寸的RGB接口屏幕。这听起来像是个简单的“接线-点亮”的活儿,但真上手了才发现,从硬件引脚匹配、设…...
方法区内存回收机制与核心引用链深度剖析
在 Java 虚拟机(JVM)的内存管理体系中,方法区(JDK 1.8 及以后具体实现为元空间 Metaspace)的垃圾回收主要聚焦于两部分:废弃的常量池清理以及无用类的卸载(Class Unloading)。由于类…...
IT6520:USB‑C 转 MIPI 芯片方案 4K@120Hz 高清显示
一、前言平板、便携屏、AR/VR 头显、车载中控、会议终端等设备,对USB‑C 一线通视频输出的需求越来越强。 传统方案必须用:PD 控制器 DP 接收芯片 MIPI 桥接芯片 外置 MCU Flash,多芯片拼凑导致电路复杂、成本高、兼容性差、开发周期长。…...
别再凭感觉布线了!用ADS仿真手把手教你搞定PCB信号完整性的5种端接方案
高速PCB设计实战:5种端接方案在ADS中的精准仿真与选型指南 当你在深夜盯着示波器上扭曲的方波和顽固的振铃时,是否曾怀疑过自己的PCB设计生涯?信号完整性不是玄学,而是一门可以通过仿真精确控制的工程艺术。本文将用Keysight ADS&…...
FanControl完全指南:5步打造Windows风扇智能控制系统
FanControl完全指南:5步打造Windows风扇智能控制系统 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trending/fa/…...
数据结构:2.时间复杂的和空间复杂度
【目标】1.如何衡量一个算法的好坏2.复杂度3.算法效率1.如何衡量一个算法的好坏?1.1 两大核心指标(理论层面)指标问的问题表示法例子时间复杂度数据量增大,耗时怎么增长?大O表示法O(n) 比 O(n) 好空间复杂度数据量增大…...
UVM验证中的迭代模式:从寄存器遍历到配置组合的实战应用
1. 项目概述:为什么要在UVM中谈迭代模式?如果你做过芯片验证,尤其是用SystemVerilog和UVM搭过测试平台,那你肯定对“遍历”这个概念不陌生。比如,你需要检查一个存储阵列里每一个地址的读写是否正确,或者需…...
Hermes Agent 权限分级实战:3 级凭证隔离配置与 4 类越权风险规避
1. 权限不是加个 if 就完事:Hermes Agent 的凭证隔离为什么必须分三级 我第一次在生产环境上线 Hermes Agent 时,给所有子智能体(sub-agent)统一配了同一个数据库只读账号。逻辑很朴素:「反正只读,能出什么问题?」——直到某天凌晨三点,监控告警显示核心订单库被高频扫…...
