当前位置: 首页 > news >正文

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文件中反序列化指定类型的对象&#xff1a; Winform中实现序列化指定类型的对象到指定的Xml文件和从指定的Xml文件中反序列化指定类型的对象_winform xml序列化_霸道流氓气质的博客-CSDN博客 上面讲的序…...

基于python的超市历年数据可视化分析

人生苦短 我用python Python其他实用资料:点击此处跳转文末名片获取 数据可视化分析目录人生苦短 我用python一、数据描述1、数据概览二、数据预处理0、导入包和数据1、列名重命名2、提取数据中时间&#xff0c;方便后续分析绘图三、数据可视化1、美国各个地区销售额的分布&…...

GPT-4技术报告

摘要 链接&#xff1a;https://cdn.openai.com/papers/gpt-4.pdf 我们汇报了GPT-4的发展&#xff0c;这是一个大规模的多模态模型&#xff0c;可以接受图像和文本输入并产生文本输出。虽然在许多现实场景中&#xff0c;GPT-4的能力不如人类&#xff0c;但它在各种专业和学术基…...

前端性能优化

总结 使用打包工具对代码进行打包压缩&#xff1b;引入css时采用link标签&#xff0c;并放入头部&#xff0c;使其与文档一起加载&#xff0c;减少页面卡顿时间&#xff1b;尽量减少dom结构的重排和重绘&#xff1b;使用css雪碧图&#xff0c;减少网络请求&#xff1b;对不同分…...

尚医通-(三十三)就诊人管理功能实现

目录&#xff1a; &#xff08;1&#xff09;前台用户系统-就诊人管理-需求说明 &#xff08;2&#xff09;就诊人管理-接口开发-列表接口 &#xff08;3&#xff09;就诊人管理-接口开发-其他接口 &#xff08;4&#xff09;前台用户系统-就诊人管理-前端整合 &#xff0…...

《Spring Boot 趣味实战课》读书笔记(二)

牛刀小试——五分钟入门 Spring Boot 万物皆可 Hello World 创建一个 Web 工程 填写项目信息 选择依赖 从 IDEA 打开下载好的 Spring Boot 工程&#xff1a; 完成核心代码 创建 HelloController 类并编写 hello 方法 创建一个 HelloController 类&#xff0c;或者选择 Fi…...

Spring Cloud -- GateWay

为什么需要网关在微服务架构中&#xff0c;一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢&#xff1f;如果没有网关的存在&#xff0c;我们只能在客户端记录每个微服务的地址&#xff0c;然后分别去调用。这样的话会产生很多问题&#xff0c;例…...

【C语言】memcpy , memset等内存操作函数使用方法与注意事项

这个章节&#xff0c;我们探讨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++)

持续更新&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 网络部分 1.问&#xff0c;四次挥手的过程&#xff0c;和双方状态变化&#xff1f; 挥手这前&#xff0c;两边都是established状态&#xff0c;客户端发起断开请求&#xff0c;向服务器发送fin请求&…...

androidx.appcompat 升级到1.5.1 趟过的坑

APP 要上google play&#xff0c;Android SDK 版本要升级到32&#xff1b;接了一个第三方SDK&#xff0c;不巧的是这个SDK引用appcompat是1.5.1&#xff0c;顺手把appcompat 包升级到1.5.1&#xff0c;这草率的一升&#xff0c;带来的不止一地鸡毛&#xff0c;还有精神上被残忍…...

[C++]反向迭代器

目录 前言&#xff1a; 1 对反向迭代器的构造思想 2 实现反向迭代器 3 完整代码 前言&#xff1a; 本篇文章主要介绍了STL容器当中的反向迭代器&#xff0c;可能有朋友会说&#xff1a;“反向迭代器有什么好学的&#xff1f;不一样还是迭代器吗&#xff0c;我正向能写出来&…...

解析Python编程中的包结构

假设你想设计一个模块集&#xff08;也就是一个“包”&#xff09;来统一处理声音文件和声音数据。通常由它们的扩展有不同的声音格式&#xff0c;例如&#xff1a;WAV&#xff0c;AIFF&#xff0c;AU&#xff09;&#xff0c;所以你可能需要创建和维护一个不断增长的各种文件格…...

【前端】深入浅出缓存原理

缓存的基本原理 对于前端来说&#xff0c;缓存主要分为浏览器缓存&#xff08;比如 localStorage、sessionStorage、cookie等等&#xff09;以及http缓存&#xff0c;也是本文主要讲述的。 当然叫法也不一样&#xff0c;比如客户端缓存大概包括浏览器缓存和http缓存 所谓htt…...

单调栈图文详解(附Java模板)

&#x1f34f;&#x1f350;&#x1f34a;&#x1f351;&#x1f352;&#x1f353;&#x1fad0;&#x1f951;&#x1f34b;&#x1f349;&#x1f95d; 啥是"单调栈"&#xff0c;它能解决什么样的问题&#xff1f; 文章目录&#x1f9a9;单调栈的概念&a…...

彻底理解Session、Cookie、Token,入门及实战

文章目录Session Cookie的使用Token的使用Session Cookie的使用 1. Session存储数据 HttpSession session request.getSession(); //Servlet底层通过的SESSIONID&#xff0c;获取Session对象。 session.setAttribute("loginTime",new Date()); out.println(&q…...

为什么运营商大数据可以精准获客?

“获客难”&#xff0c;“获客成本高”&#xff0c;一直是困扰企业的大问题&#xff0c;身边的许多朋友在吐槽客户的意向度不高&#xff0c;总是无法成交&#xff0c;员工非常积极主动去跟踪客户了&#xff0c;但始终事倍功半&#xff0c;这就像是老人们常说的一句老话“热脸贴…...

【数据结构】栈的实现

&#x1f4af;&#x1f4af;&#x1f4af; 本篇主要利用数组来实现栈&#xff0c;对于栈的各种操作都作详细介绍&#xff0c;压栈&#xff0c;出栈以及获取栈中元素的操作都是学习栈的必备知识&#xff0c;快来学起来吧&#xff01;&#xff01;&#xff01;©Ⅰ.栈的概念及…...

【链表OJ题(六)】链表分割

​ ​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;数据结构 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 文章目录链表OJ题(六)1. 链表…...

C++类中的三大函数(构造,析构,拷贝)

下面一段话与大家共勉&#xff1a;每个人的一生都会遇到很多边界&#xff0c;有些边界可以突破&#xff0c;有些则不能。那些无法突破的边界就是你的极限&#xff0c;而划分边界的标准就是“阈值”。每次突破阈值之后&#xff0c;人生轨迹就会发生剧烈变化&#xff0c;其间需要…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...