C#使用ini-parser循环AddKey添加键仅保留最后一项的问题
问题原因
ini-parser 默认配置的两个逻辑会导致该现象:
- 默认会自动裁剪键名、值首尾的空白、包裹引号等特殊字符,手动给键名拼接双引号时,不同的原始键名可能被归一化为相同字符串,触发重复键覆盖
- 默认重复键处理策略为保留最后一次写入的值,出现同名键时不会抛出异常,直接覆盖旧值,最终文件中只会留下最后一次循环写入的键值对
- 手动给值拼接
{}包裹符也可能触发值的自动裁剪,导致写入逻辑异常
把WriteFile移入循环之所以能生效,是因为每次循环都会把当前内存中的全量数据重写到文件,本质是反复覆盖文件,IO开销极高,不推荐使用。
正确解决方案
不要手动给键名、值拼接引号、大括号类包裹符号,先修改解析器默认配置避免静默覆盖,所有键添加完成后一次性写入文件即可,参考实现如下:
var parser = new FileIniDataParser(); // 调整解析器配置 parser.Parser.Configuration.DuplicateKeysBehaviour = IniParser.Configuration.DuplicateKeyBehaviour.ThrowError; // 出现重复键直接抛出错误,方便定位问题 parser.Parser.Configuration.TrimKeys = false; // 关闭键名自动裁剪,避免自定义键名被篡改 parser.Parser.Configuration.TrimValues = false; // 关闭值自动裁剪 IniData data = parser.ReadFile("devreorder.ini"); int deviceIndex = 0; foreach (DeviceInstance di in Manager.GetDevices(DeviceClass.GameControl, EnumDevicesFlags.AttachedOnly)) { // 直接使用原始设备名作为键,如果存在同名设备可以追加索引保证唯一 string keyName = deviceIndex == 0 ? di.ProductName : $"{di.ProductName}_{deviceIndex}"; string keyValue = di.InstanceGuid.ToString(); if (data["ALL"].ContainsKey(keyName)) { data["ALL"][keyName] = keyValue; } else { data["ALL"].AddKey(keyName, keyValue); } deviceIndex++; } // 所有键添加完成后一次性写入 parser.WriteFile("devreorder.ini", data);
如果运行时抛出重复键错误,说明设备列表中存在同名产品,给键名追加唯一后缀(比如设备索引、实例哈希值)保证键名唯一即可。
内容的提问来源于stack exchange,提问作者Haim
相关产品推荐
相关产品推荐

