最稳妥的INI读取方式是Windows API的GetPrivateProfileString,它经三十年验证,自动处理注释、空白、嵌套等号及大小写归一化;.NET Core/5+需用自研纯托管解析器模拟Windows语义。
直接用 Windows API 的
是最稳妥、最兼容的读取方式,尤其在 .NET Framework 或需要保持与传统桌面软件行为一致时;.NET Core / .NET 5+ 项目若需跨平台,则不能依赖该 API,必须换方案。
为什么不用自己解析或第三方库
INI 看似结构简单,但真实配置文件常含空行、分号注释、等号在值中(如
)、BOM、混合编码(ANSI/UTF-8)、大小写混用节名。手写正则或
+ 字符串分割极易漏掉边界情况——比如把
当成键值行,或把注释行里的等号误判为分隔符。第三方库(如
)虽省事,但 NuGet 包版本更新后可能破坏原有大小写策略或转义逻辑,且多数不处理 Windows 特有的“节名不区分大小写”语义。
Windows 系统级 API 经过三十年验证,自动跳过注释、忽略空白、正确识别嵌套等号、支持大小写归一化——你不需要重造轮子,只要调对它。
的典型调用陷阱
常见错误不是代码写错,而是参数传得不对:
路径必须是
绝对路径
:
不认相对路径,
会被解释为当前工作目录下,而非 EXE 所在目录;应先用
或
拼出完整路径
缓冲区大小要含结尾
:传
时,API 最多写入 255 字符 + 1 个
;若值超长,返回长度为 255,但字符串被截断——建议统一用
返回值不是成功标志:函数返回实际写入字符数(不含
),返回
可能是键不存在,也可能是值为空字符串;判断是否存在应传默认值
,再比对结果是否等于该默认值
中文乱码往往源于编码不匹配:若 INI 文件是 ANSI(如 GBK),而 C# 字符串按 UTF-16 传入,API 会按当前系统 ACP 解码——确保文件保存为系统默认 ANSI 编码,或改用
写入前先用
验证
.NET Core / .NET 5+ 项目怎么安全读取
Windows API 在非 Windows 平台不可用,且
仅限 .NET Framework。此时唯一可靠做法是引入轻量、无依赖的纯托管解析器,但必须满足:
C知道
CSDN推出的一款AI技术问答工具
下载
支持节名和键名大小写不敏感匹配(模拟 Windows 行为)
跳过以
或
开头的整行注释
允许值中含等号(只认第一个等号为分隔符)
保留原始行末换行符,避免因
丢失空行语义
可基于
流式解析,核心逻辑约 40 行即可覆盖 95% 场景。不推荐用 JSON/YAML 替代 INI——用户习惯、部署工具链、旧设备兼容性都卡在这里。
读取后别直接当配置对象用
INI 是扁平文本,没有类型信息。读出的
是字符串,不是
;
不是布尔值。不要在读取层做隐式转换,容易在空值、格式错误时崩。应在业务层用
或自定义转换器封装,例如:
更关键的是:别把
实例长期缓存并复用——Windows API 不保证线程安全,且文件可能被外部进程修改;每次读取都应视为一次独立 I/O 操作,必要时加文件锁或用
做变更通知。
GetPrivateProfileStringpath=C:\a=b\cFile.ReadAllLines[Section]ini-parserGetPrivateProfileStringGetPrivateProfileString"config.ini"AppContext.BaseDirectoryAssembly.GetExecutingAssembly().Location\0new StringBuilder(256)\0new StringBuilder(32767)\00""WritePrivateProfileStringEncoding.Default.GetBytes()Microsoft.VisualBasic.FileIO.IniParser;#ReadAllLinesFile.ReadLines"30"int"true"int.TryParsepublic static int ReadInt(this IniReader reader, string section, string key, int defaultValue = 0)
{
if (int.TryParse(reader.ReadString(section, key), out var v)) return v;
return defaultValue;
}IniReaderFileSystemWatcher