在C#开发中,尽管JSON和XML更流行,但很多遗留系统和工控软件仍使用INI文件保存配置。INI以节区(section)组织键值对,结构直观、人工编辑方便。要在C#中操作它,最稳妥的办法是调用Windows API,而不是自己写正则解析。

一、INI文件基础结构
一个典型的INI文件由若干节区组成,每个节区用方括号包裹名称,其下为key=value形式的配置项。注释以分号开头。例如下面这段配置描述了数据库连接与界面设置:
[Database] Server=127.0.0.1 Port=3306 User=root [UI] Theme=Dark FontSize=12 ; 这是注释行
这种格式对人工修改友好,但在C#里若用File.ReadAllLines自行切分,容易在空行、多余空格、BOM编码上出问题。尤其是系统目录下的INI,Windows自身使用特殊缓存机制,直接覆盖文件可能不会立即生效。
因此,使用系统提供的API不仅能正确处理节区定位,还能兼容系统对INI的私有缓存。理解这一点,是写出稳定配置模块的前提。
二、通过Windows API实现读写
C#本身位于.NET托管环境,而INI读写函数位于kernel32.dll中。我们可以通过DllImport特性引入两个核心函数:GetPrivateProfileString用于读,WritePrivateProfileString用于写。下面给出声明代码:
using System;
using System.Runtime.InteropServices;
using System.Text;
public class IniHelper
{
[DllImport("kernel32", CharSet = CharSet.Unicode)]
private static extern int GetPrivateProfileString(
string section,
string key,
string defaultValue,
StringBuilder retVal,
int size,
string filePath);
[DllImport("kernel32", CharSet = CharSet.Unicode)]
private static extern bool WritePrivateProfileString(
string section,
string key,
string value,
string filePath);
}
在上面的代码中,CharSet设为Unicode可避免中文路径或中文配置值出现乱码。GetPrivateProfileString要求传入一个StringBuilder作为接收缓冲,size参数指定其容量。WritePrivateProfileString在key传null时可删除整个节区,value传null时可删除某个键。
需要注意的是,如果INI文件位于系统目录(如Windows目录),普通用户可能没有写入权限,且系统会重定向到虚拟存储。因此建议将配置文件放在应用程序目录下,或使用Environment.GetFolderPath获取本地数据目录。
三、封装实用的读写方法
仅声明API还不够,我们需要把它们包装成易用的方法。下面示例展示如何读取字符串、写入字符串,以及读取整数和枚举所有节区:
public string ReadString(string section, string key, string path, string def = "")
{
StringBuilder sb = new StringBuilder(1024);
GetPrivateProfileString(section, key, def, sb, sb.Capacity, path);
return sb.ToString();
}
public void WriteString(string section, string key, string value, string path)
{
WritePrivateProfileString(section, key, value, path);
}
public int ReadInt(string section, string key, string path, int def = 0)
{
string s = ReadString(section, key, path, def.ToString());
return int.TryParse(s, out int r) ? r : def;
}
上述ReadString方法分配了1KB缓冲,对绝大多数配置项足够。若配置值可能超长,可增大StringBuilder容量。ReadInt则复用字符串读取并做安全转换,避免格式异常导致程序中断。
对于写入,WritePrivateProfileString会自动创建不存在的节区或键。如果文件不存在,系统也会尝试在指定路径新建文件,但父目录必须存在,否则返回false。调用后应检查返回值以确保写入成功。
四、常见问题与避坑建议
开发者常遇到的一个误区是:用StreamWriter写好INI后,再用API去读却读不到。这是因为Windows对INI有内部缓存,混合使用不同写入方式会不一致。统一用API写入是最安全的做法。
| 问题现象 | 产生原因 | 解决方式 |
|---|---|---|
| 中文变问号 | API用ANSI字符集 | DllImport设CharSet.Unicode |
| 修改不生效 | 系统INI缓存 | 统一API读写,避免手动改文件 |
| 写文件失败 | 目录无权限 | 改存用户本地数据目录 |
此外,INI不支持多层嵌套,若你的配置关系复杂,应考虑改用JSON。但针对简单的单机工具,INI配合本文封装类,足以覆盖绝大部分场景,且零依赖、体积小。
最后提醒,INI值不要存放敏感明文密码。如必须存,至少做简单加密再写入,读取时解密,降低泄露风险。
C#_INIINI读写GetPrivateProfileString修改时间:2026-08-01 15:48:27