C# 单例模式,ini、csv、xml文件读写

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;

namespace HelpTool
{
	/// <summary>
    /// 单类模板类
    /// </summary>
    /// <typeparam name="T"></typeparam>
	public class SingleTemplate<T> where T : class, new()
	{
		/// <summary>
		/// 
		/// </summary>
		public static object Lock_m = new object();
		/// <summary>
		/// 
		/// </summary>
		private static T InstanceT_m;

		/// <summary>
		/// 获取类的实例;没有创建,有则获取
		/// </summary>
		public static T Instance
		{
			get
			{
				lock (Lock_m)
				{
					if (InstanceT_m == null)
					{
						InstanceT_m = Activator.CreateInstance<T>();
					}
				}

				return InstanceT_m;
			}
		}

		/// <summary>
		/// 窗口显示日志委托
		/// </summary>
		/// <param name="log">日志内容</param>
		public delegate void FromShowLog(string log);
		/// <summary>
		/// 窗口显示日志事件
		/// </summary>
		public event FromShowLog EventFromShowLog;
		/// <summary>
		/// 窗口显示日志
		/// </summary>
		/// <param name="log"></param>
		public void ShowLog(string log)
		{
			EventFromShowLog?.Invoke(log);
		}
	}

	/// <summary>
	/// 文件操作管理类(xml、ini、csv)
	/// </summary>
	public class ConfigFileMgr : SingleTemplate<ConfigFileMgr>
	{
		//声明API函数
		[DllImport("kernel32", CharSet = CharSet.Unicode)]
		private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);

		[DllImport("kernel32", CharSet = CharSet.Unicode)]
		private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);

		[DllImport("kernel32")]
		private static extern bool WritePrivateProfileString(byte[] section, byte[] key, byte[] val, string filePath);
		[DllImport("kernel32")]
		private static extern int GetPrivateProfileString(byte[] section, byte[] key, byte[] def, byte[] retVal, int size, string filePath);
		
		/// <summary>
		/// 系统参数保存路径
		/// </summary>
		public string ParamPath_m = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config", "SystemParam_Config.xml");

		/// <summary>
		/// XML文件读写测试
		/// </summary>
		public void XmlReadWriteTest()
		{
			string strRootNode = "SystemCfg";
			string[] keys = new string[] { "范围上限", "范围下限", "补偿值" };
			string[] subNodes = new string[] { "节点0", "节点1", "节点2", "节点3", "节点4", "补偿" };
			List<string[]> testData = new List<string[]>();
			for (int j = 0; j < 10; j++)
			{
				string[] values = new string[keys.Length];
				for (int i = 0; i < keys.Length; i++)
				{
					values[i] = "测试值" + i;
				}
				testData.Add(values);
			}
			SaveCfgXML(ParamPath_m, strRootNode, subNodes, keys, testData);

			XmlDocument xml = new XmlDocument();
			xml.Load(ParamPath_m);
			ReadCfgXml(xml, strRootNode, subNodes, keys, out testData);
		}

		/// <summary>
		/// 异步保存CSV文件
		/// </summary>
		/// <param name="filePath">路径</param>
		/// <param name="title">标题</param>
		/// <param name="data">数据内容</param>
		public void SaveFileCsvTask(string filePath, string title, string[] data)
		{
			Task.Run(delegate
			{
				string dirPath = Path.GetDirectoryName(filePath);
				if (!Directory.Exists(dirPath))
				{
					Directory.CreateDirectory(dirPath);
				}

				bool bFile = File.Exists(filePath);

				try
				{
					FileStream fs;
					using (fs = File.Open(filePath, FileMode.Append))
					{
						StreamWriter sw = new StreamWriter(fs, Encoding.UTF8);

						if (!bFile)
						{
							sw.WriteLine(title);
						}
						for (int i = 0; i < data.Length; i++)
						{
							sw.WriteLine(data[i]);
						}

						sw.Close();
						fs.Close();
					}
				}
				catch
				{

				}
			});
		}

		/// <summary>
		/// 读取CSV文件数据
		/// </summary>
		/// <param name="filePath">文件路径</param>
		/// <param name="resultData">数据</param>
		/// <param name="error">读取失败返回的错误信息</param>
		/// <returns></returns>
		public bool ReadFileCsv(string filePath, out List<string[]> resultData, out string error)
		{
			error = "";
			resultData = new List<string[]>();
			if (File.Exists(filePath))
			{
				try
				{
					FileStream fs = File.OpenRead(filePath);
					StreamReader sr = new StreamReader(fs, Encoding.Default);

					while (!sr.EndOfStream)
					{
						string temp = sr.ReadLine();
						string[] tempArray = temp.Split(',');
						resultData.Add(tempArray);
					}

					sr.Close();
					fs.Close();
				}
				catch (Exception ex)
				{
					error = ex.Message.ToString();
					return false;
				}
			}

			return true;
		}

		/// <summary> 
		/// 写入INI文件 
		/// </summary> 
		/// <param name="filePath">文件路径</param> 
		/// <param name="section">节点名称(如 [TypeName] )</param> 
		/// <param name="key">键</param> 
		/// <param name="value">值</param> 
		public void IniWriteValueString(string filePath, string section, string key, string value)
		{
			WritePrivateProfileString(section, key, value, filePath);
		}

		/// <summary> 
		/// 读出INI文件 
		/// </summary> 
		/// <param name="filePath">文件路径</param> 
		/// <param name="section">节点名称(如 [TypeName] )</param> 
		/// <param name="key">键</param> 
		public string IniReadValueString(string filePath, string section, string key)
		{
			StringBuilder temp = new StringBuilder(1024);
			int size = GetPrivateProfileString(section, key, "", temp, 1024, filePath); ;
			return temp.ToString();
		}

		/// <summary> 
		/// 读出INI文件 
		/// </summary> 
		/// <param name="filePath">文件路径</param> 
		/// <param name="section">节点名称(如 [TypeName] )</param> 
		/// <param name="key">键</param> 
		/// <param name="encodingName">编码格式名称</param> 
		/// <param name="size">读取字符大小</param> 
		public string IniReadValueByte(string filePath, string section, string key, string encodingName = "UTF-8", int size = 1024)
		{
			byte[] buffer = new byte[size];
			int count = GetPrivateProfileString(getBytes(section, encodingName), getBytes(key, encodingName),
												getBytes("", encodingName), buffer, size, filePath);
			return Encoding.GetEncoding(encodingName).GetString(buffer, 0, count).Trim();
		}
		/// <summary> 
		/// 写入INI文件 
		/// </summary> 
		/// <param name="filePath">文件路径</param> 
		/// <param name="section">节点名称(如 [TypeName] )</param> 
		/// <param name="key">键</param> 
		/// <param name="value">值</param> 
		/// <param name="encodingName">编码格式名称</param> 
		public bool IniWriteValueByte(string filePath, string section, string key, string value, string encodingName = "utf-8")
		{
			return WritePrivateProfileString(getBytes(section, encodingName), getBytes(key, encodingName), getBytes(value, encodingName), filePath);
		}
		private byte[] getBytes(string str, string encodingName)
		{
			return null == str ? null : Encoding.GetEncoding(encodingName).GetBytes(str);
		}
		
		/// <summary>
		/// 从xml文件中读取指定节点-指定属性的值
		/// </summary>
		/// <param name="xmlDoc">已打开的xml文档</param>
		/// <param name="strRootNode">根节点,与文件根节点要一致</param>
		/// <param name="strSubNode">子节点,索引0:一级子节点,1:二级子节点,以此类推</param>
		/// <param name="attributeKeys">属性的键</param>
		/// <param name="attributeValues">属性的值,string[]与attributeKeys是键值对的关系,即长度一致,数据一一对应</param>
		public void ReadCfgXml(XmlDocument xmlDoc, string strRootNode, string[] strSubNode, string[] attributeKeys, out List<string[]> attributeValues)
		{
			attributeValues = new List<string[]>();
			if (attributeKeys.Length == 0)
			{
				return;
			}
			try
			{
				if (xmlDoc != null)
				{
					string strNodes = $"/{strRootNode}";
					for (int i = 0; i < strSubNode.Length; i++)
					{
						strNodes += $"/{strSubNode[i]}";
					}
					XmlNodeList xmlNode = xmlDoc.SelectNodes(strNodes);
					if (xmlNode.Count > 0)
					{
						xmlNode = xmlNode.Item(0).ChildNodes;
						for (int i = 0; i < xmlNode.Count; i++)
						{
							XmlElement xeNode = (XmlElement)xmlNode[i];
							string[] values = new string[attributeKeys.Length];
							for (int j = 0; j < attributeKeys.Length; j++)
							{
								values[j] = xeNode.GetAttribute(attributeKeys[j]);
							}
							attributeValues.Add(values);
						}
					}
				}
			}
			catch (Exception)
			{

			}
		}

		/// <summary>
		/// 保存内存项目数据(SN、型号、用户信息)到xml文件
		/// </summary>
		/// <param name="fileCfgPath">需要保存的xml文档路径</param>
		/// <param name="strRootNode">根节点(若文件存在根节点要一致,否则出错;若不存在则创建)</param>
		/// <param name="strSubNode">子节点,索引0:一级子节点,1:二级子节点,以此类推</param>
		/// <param name="attributeKeys">属性的键</param>
		/// <param name="attributeValues">属性的值,string[]与attributeKeys是键值对的关系,即长度一致,数据一一对应</param>
		public bool SaveCfgXML(string fileCfgPath, string strRootNode, string[] strSubNode, string[] attributeKeys, List<string[]> attributeValues)
		{
			try
			{
				if (Path.GetExtension(fileCfgPath).ToLower() != ".xml")
				{
					return false;
				}

				XmlDocument xmlDoc = new XmlDocument();
				if (!Directory.Exists(Path.GetDirectoryName(fileCfgPath)))
				{
					Directory.CreateDirectory(Path.GetDirectoryName(fileCfgPath));
				}
				bool bFile = File.Exists(fileCfgPath);
				if (!bFile)
				{
					//创建Xml声明部分,即<?xml version="1.0" encoding="utf-8" ?>
					XmlDeclaration Declaration = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", null);
					xmlDoc.InsertBefore(Declaration, xmlDoc.DocumentElement);
					XmlNode rootNode = xmlDoc.CreateElement(strRootNode);//创建主节点
					xmlDoc.AppendChild(rootNode);

					if (strSubNode.Length > 0)
					{
						XmlNode nodeSub = xmlDoc.CreateElement(strSubNode[0]);//创建一级子节点
						rootNode.AppendChild(nodeSub);
						for (int i = 1; i < strSubNode.Length; i++)
						{
							XmlNode nodeSub1 = xmlDoc.CreateElement(strSubNode[i]);//创建次级子节点
							nodeSub.AppendChild(nodeSub1);
							nodeSub = nodeSub1;
						}
					}
				}
				else
				{
					xmlDoc.Load(fileCfgPath);
					XmlNode rootNode = xmlDoc.DocumentElement;//获取根节点
					if (rootNode != null && rootNode.Name != strRootNode)
					{
						return false;
					}

					XmlNode nodeMain = xmlDoc.SelectSingleNode(strRootNode);
					if (nodeMain == null)
					{
						nodeMain = xmlDoc.CreateElement(strRootNode);
						rootNode.AppendChild(nodeMain);
						if (strSubNode.Length > 0)
						{
							for (int i = 0; i < strSubNode.Length; i++)
							{
								XmlNode nodeSub = xmlDoc.CreateElement(strSubNode[i]);//创建次级子节点
								nodeMain.AppendChild(nodeSub);
								nodeMain = nodeSub;
							}
						}
					}
					else
					{
						if (strSubNode.Length > 0)
						{
							string strNodes = $"/{strRootNode}/{strSubNode[0]}";
							XmlNode nodeSub = xmlDoc.SelectSingleNode(strNodes);//获取一级子节点
							if (nodeSub == null)
							{
								nodeSub = xmlDoc.CreateElement(strSubNode[0]);//创建次级子节点
								nodeMain.AppendChild(nodeSub);
							}

							if (strSubNode.Length > 1)
							{
								for (int i = 1; i < strSubNode.Length; i++)
								{
									strNodes += $"/{strSubNode[i]}";
									XmlNode nodeSub1 = xmlDoc.SelectSingleNode(strNodes);//获取一级子节点
									if (nodeSub1 == null)
									{
										nodeSub1 = xmlDoc.CreateElement(strSubNode[i]);//创建次级子节点
										nodeSub.AppendChild(nodeSub1);
									}
									nodeSub = xmlDoc.SelectSingleNode(strNodes);
								}
							}
							nodeSub.RemoveAll();
						}
					}
				}
				string strNodes1 = $"/{strRootNode}";
				for (int i = 0; i < strSubNode.Length; i++)
				{
					strNodes1 += $"/{strSubNode[i]}";
				}
				XmlNode xnlParam = xmlDoc.SelectSingleNode(strNodes1);
				foreach (string[] item in attributeValues)
				{
					XmlElement root = xmlDoc.CreateElement(strSubNode[strSubNode.Length - 1]);
					if (item.Length == attributeKeys.Length)
					{
						for (int i = 0; i < item.Length; i++)
						{
							root.SetAttribute(attributeKeys[i], item[i]);
						}
						xnlParam.AppendChild(root);
					}
				}
				xmlDoc.Save(fileCfgPath);//保存Xml文档
				return true;
			}
			catch (Exception ex)
			{
				return false;
			}
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值