c#操作ini文件_增删查功能的帮助类
前言
当大家搜索ini的时候就说明项目中是需要存放一些持久性变量,或者是代码程序不能满足的数据,或者是用户及程序的配置信息,不管怎么说,就是需要操作ini文件,直接上代码
using MediaInfoLib; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows.Documents; namespace INIFileHandler { public class INIFile { private string filePath; private const int MaxSectionSize = 32767; // Maximum size of a single INI section private Dictionary<string, string> keyValuePairs = new Dictionary<string, string>(); [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", CharSet = CharSet.Unicode)] private static extern int GetPrivateProfileSection(string section, IntPtr keyValuePtr, int size, string filePath); [DllImport("kernel32", CharSet = CharSet.Unicode)] private static extern int GetPrivateProfileString(string section, string key, string def, Byte[] retVal, int size, string filePath); public INIFile(string filePath) { if (!Directory.Exists(Path.GetDirectoryName(filePath))) { Directory.CreateDirectory(Path.GetDirectoryName(filePath)); if (!File.Exists(filePath))// 判断文件是否存在,不存在则创建文件 { File.Create(filePath); } } this.filePath = filePath; Load(this.filePath); } //是否有内容 public bool IsFileNotEmpty() { using (StreamReader reader = new StreamReader(this.filePath)) { return !reader.EndOfStream; } } //获取文件夹下所有的文件 这个和this.filePath不一样的,这是我项目需要的另外一个路径判断 public string[] GetFileNames(string path) { if (!Directory.Exists(path)) { Directory.CreateDirectory(path); if (!File.Exists(path)) { File.Create(path); } } string[] fileNames = Directory.GetFiles(path); return fileNames; } //写 public void WriteValue(string section, string key, string value) { WritePrivateProfileString(section, key, value, this.filePath); } //读 public string ReadValue(string section, string key) { StringBuilder retVal = new StringBuilder(255); GetPrivateProfileString(section, key, "", retVal, 255, this.filePath); return retVal.ToString(); } //通过遍历value值获取key public string FindKeyByValue(string value) { foreach (var kvp in keyValuePairs) { if (kvp.Value == value) { return kvp.Key; } } return null; // 如果找不到对应的key,则返回null } //通过节点获取key值 public List<string> ReadKeys(string section) { var keyValuePtr = Marshal.AllocCoTaskMem(MaxSectionSize * sizeof(char)); try { var keyValueLength = GetPrivateProfileSection(section, keyValuePtr, MaxSectionSize, this.filePath); if (keyValueLength > 0) { var keyValues = Marshal.PtrToStringUni(keyValuePtr, keyValueLength - 1); var pairs = keyValues.Split('\0'); var keys = new List<string>(); foreach (var pair in pairs) { var key = pair.Split('=')[0]; if (!string.IsNullOrWhiteSpace(key)) keys.Add(key); } return keys; } } finally { Marshal.FreeCoTaskMem(keyValuePtr); } return new List<string>(); } //获取所有的section 这是我自己项目,节点一般三个字固定的,我这里是写死的,你们看自己需求测试 public List<string> ReadSections(string filePath) { List<string> result = new List<string>(); List<string> resultJD = new List<string>(); Byte[] buf = new Byte[65536]; int len = GetPrivateProfileString(null,null,null,buf, buf.Length, this.filePath); int j = 0; for (int i = 0; i < len*2; i++) { if (buf[i] == 0) { result.Add(Encoding.UTF8.GetString(buf, j, i - j)); j = i + 1; } } string[] strArray = result.Where(s => !string.IsNullOrEmpty(s)).ToArray(); for (int i = 0; i < strArray.Length; i += 3) { if (i + 2 < strArray.Length) { resultJD.Add(strArray[i] + strArray[i + 1] + strArray[i + 2]); } else { // 最后一次组成少于三位元素,不组成 } } return resultJD; } public void DeleteSection(string section) { WritePrivateProfileString(section, null, null, this.filePath); } //这个是帮助类中构造函数的一个方法 private void Load(string filePath) { string[] lines = File.ReadAllLines(this.filePath, Encoding.UTF8); foreach (string line in lines) { string trimmedLine = line.Trim(); if (trimmedLine.StartsWith(";") || string.IsNullOrWhiteSpace(trimmedLine)) { continue; } int equalsIndex = trimmedLine.IndexOf("="); if (equalsIndex > 0 && equalsIndex < trimmedLine.Length - 1) { string key = trimmedLine.Substring(0, equalsIndex).Trim(); string value = trimmedLine.Substring(equalsIndex + 1).Trim(); if (!keyValuePairs.ContainsKey(key)) { keyValuePairs.Add(key, value); } } } }
// 写入键值对到 INI 文件
public void WriteToIniFile(string filePath, string key, string value)
{
using (StreamWriter writer = new StreamWriter(filePath, true))
{
writer.WriteLine($"{key}={value}");
}
}
// 通过键获取 INI 文件中的值
public string GetValueFromIniFile(string filePath, string key)
{
using (StreamReader reader = new StreamReader(filePath))
{
string line;
while ((line = reader.ReadLine()) != null)
{
if (line.StartsWith(key + "="))
{
return line.Substring(key.Length + 1);
}
}
}
return null;
}
// 清空 INI 文件内容
public void ClearIniFile(string filePath)
{
File.WriteAllText(filePath, string.Empty);
}
}
}
上面代码发现不能读写有中文的字,后查阅资料发现ini文件本身是ASCII编码格式的文件,但是我使用C#中的 Encoding.ASCII去指定编码读取ini文件中内容,发现是问号?乱码,经过改进,将传入的key和value直接指定为utf-8的格式写入,该ini文件就为nuf-8编码的格式了,读取也是这个格式,成功读取出来
1 [DllImport("kernel32")] 2 private static extern long WritePrivateProfileString(string section, 3 byte[] key, byte[] val, string filePath); 4 5 [DllImport("kernel32")] 6 private static extern int GetPrivateProfileString(string section, 7 string key, string def, Byte[] retVal, 8 int size, string filePath); 9 10 //写 11 public void WriteValue(string section, string key, string value) 12 { 13 WritePrivateProfileString(section, Encoding.UTF8.GetBytes(key), Encoding.UTF8.GetBytes(value), this.filePath); 14 15 } 16 17 //读 18 public string ReadValue(string section, string key) 19 { 20 /*StringBuilder retVal = new StringBuilder(2550); 21 GetPrivateProfileString(section, key, "", retVal, 2550, this.filePath); 22 return retVal.ToString();*/ 23 24 byte[] Buffer = new byte[1024]; 25 int bufLen = GetPrivateProfileString(section, key, "", Buffer, Buffer.GetUpperBound(0), this.filePath); 26 string s = Encoding.UTF8.GetString(Buffer, 0, bufLen); 27 return s; 28 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)