C#通过P/Invoke读写INI配置文件的完整类实现
在C#开发中,有时需要处理传统的INI配置文件。本文提供了一种不依赖第三方库的方法,通过P/Invoke直接调用Windows核心API(kernel32.dll)来实现INI文件的读写操作,代码轻量且兼容性好。
为什么选择P/Invoke方式
C#本身对XML(如App.config或自定义XML)提供了完善的支持,但对于历史遗留或特定软件规范的INI格式,直接操作注册表或外部DLL往往是最高效的解决方案。通过使用 DllImport,我们可以在 .NET Framework 或 .NET Core/.NET 5+ 环境中直接复用 Win32 API,避免了引入庞大的 XML 解析开销或额外的 NuGet 包。
准备工作
- 环境要求:任何支持 P/Invoke 的 C# 项目(包括 Windows Forms、WPF 或 ASP.NET Core)。
- 基础概念:熟悉 INI 文件的结构(Section段、Key键、Value值)以及
StringBuilder的内存分配机制。
第1步:导入必要的命名空间
首先需要声明用于互操作服务(Interop Services)的命名空间,这是调用非托管代码的基础:
using System;
using System.Runtime.InteropServices;
using System.Text;
第2步:创建INIFile类并定义API接口
创建一个公共类 INIFile,并在其中使用 [DllImport("kernel32")] 属性声明两个核心系统函数:
WritePrivateProfileString:用于写入或更新配置项。GetPrivateProfileString:用于从文件中检索配置值。
此外,为了方便获取二进制数据(某些情况下比字符串更安全),还可以重载一个返回字节数组版本的读取函数。
完整代码实现
以下是经过整理和优化的完整 INIFile 类代码。该类封装了路径管理、写入、读取及清除功能:
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace DotNet.Utilities
{
/// <summary>
/// INI文件读写类。
/// </summary>
public class INIFile
{
// 存储INI文件的物理路径
public string path;
// 构造函数,初始化时指定配置文件路径
public INIFile(string INIPath)
{
path = INIPath;
}
// 声明内核API函数:写入INI文件
[DllImport("kernel32")]
private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
// 声明内核API函数:读取字符串类型值
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
// 声明内核API函数:读取字节数组类型值
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section, string key, string defVal, Byte[] retVal, int size, string filePath);
/// <summary>
/// 写INI文件:向指定节和键写入值
/// </summary>
/// <param name="Section">节名</param>
/// <param name="Key">键名</param>
/// <param name="Value">要写入的值</param>
public void IniWriteValue(string Section, string Key, string Value)
{
WritePrivateProfileString(Section, Key, Value, this.path);
}
/// <summary>
/// 读取INI文件:返回指定键对应的字符串值
/// </summary>
/// <param name="Section">节名</param>
/// <param name="Key">键名</param>
/// <returns>如果找不到则返回空字符串</returns>
public string IniReadValue(string Section, string Key)
{
// 预分配内存缓冲区,防止截断
StringBuilder temp = new StringBuilder(255);
int i = GetPrivateProfileString(Section, Key, "", temp, 255, this.path);
return temp.ToString();
}
/// <summary>
/// 读取INI文件:以字节数组形式返回原始数据
/// </summary>
public byte[] IniReadValues(string section, string key)
{
byte[] temp = new byte[255];
int i = GetPrivateProfileString(section, key, "", temp, 255, this.path);
return temp;
}
/// <summary>
/// 删除ini文件下所有段落(清空整个文件)
/// </summary>
public void ClearAllSection()
{
// 将section和key设为null可清空整个文件
IniWriteValue(null, null, null);
}
/// <summary>
/// 删除ini文件下指定段落下的所有键
/// </summary>
/// <param name="Section">目标段落名称</param>
public void ClearSection(string Section)
{
// 将key设为null仅清空该段下的所有键值对,保留段名结构
IniWriteValue(Section, null, null);
}
}
}
关键参数说明
section:INI文件中的方括号部分,例如 [Database]。key:等号左侧的配置项名称,例如ServerAddr。val:等号右侧的具体数值。def:当指定的键不存在时的默认返回值。
注意事项
- 路径权限:确保程序有权限读写目标INI文件所在目录。如果部署在服务器或受限环境,建议使用绝对路径或用户配置目录(如
Application.UserAppDataPath)。 - 编码问题:
kernel32.dll的 API 内部通常使用 ANSI 编码。如果配置文件包含中文等非ASCII字符,在某些区域设置的系统上可能会乱码。建议尽量使用 ASCII 字符,或在保存时注意本地化设置。 - 线程安全:该类的底层 API 不是线程安全的。如果在多线程环境下并发读写同一个INI文件,建议添加锁机制或使用静态同步方法。
总结
上述C#类提供了一个非常轻量级的解决方案来管理INI配置文件。相较于全功能的XML序列化或复杂的注册表操作,这种封装代码量少、逻辑清晰,非常适合小型工具、旧系统维护或简单的应用偏好设置存储。
以上就是C#通过P/Invoke读写INI配置文件的详细内容,更多关于C#配置管理相关资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









