一、INI文件概述
1、文件结构
节(Section):用[]包裹的逻辑分组
键值对(Key-Value):=连接的基础配置项
注释:以;或#开头的内容
[Database] ; 配置节(Section)
Server = 127.0.0.1 ; 键值对(Key=Value)
Port = 3306 # 支持分号和井号注释
[Logging]
Path = C:\App\Logs ; 路径建议使用反斜杠转义
2、设计初衷
INI文件一开始是为解决早期DOS/Win3.x系统缺乏统一配置管理的问题。
其设计核心包括:
- 创建人类可读的纯文本格式;
- 实现零依赖的轻量化配置存储;
- 支持跨平台基础配置等。
3、应用场景
在软件开发中,INI文件作为轻量级配置文件格式,因其结构简洁直观、低解析开销备受开发者青睐。时至今日,INI文件也一直活跃在工业控制软件、嵌入式设备、或经典游戏中。
二、C#原生操作方案
1、使用kernel32 API
using System.Runtime.InteropServices;
using System.Text;
public class IniHelper
{
[DllImport("kernel32", CharSet = CharSet.Unicode)]
private static extern long WritePrivateProfileString(
string section, string key, string value, string filePath);
[DllImport("kernel32", CharSet = CharSet.Unicode)]
private static extern int GetPrivateProfileString(
string section, string key, string defaultValue,
StringBuilder result, int size, string filePath);
// 封装写入方法
public static void WriteValue(string filePath, string section,
string key, string value)
{
WritePrivateProfileString(section, key, value, filePath);
}
// 封装读取方法
public static string ReadValue(string filePath, string section,
string key, string defaultValue = "")
{
var result = new StringBuilder(255);
GetPrivateProfileString(section, key, defaultValue,
result, 255, filePath);
return result.ToString();
}
}
使用示例:
// 写入配置
IniHelper.WriteValue("config.ini", "Database", "Server", "127.0.0.1");
// 读取配置
string port = IniHelper.ReadValue("config.ini", "Network", "Port", "8080");
2、注意事项
- 路径规范:
// 推荐使用绝对路径
string configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.ini");
- 类型转换:
// 读取数值型配置
int interval = int.Parse(IniHelper.ReadValue(configPath, "Settings", "Interval", "5000"));
- 线程安全:
private static readonly object _lockObj = new object();
public static void SafeWrite(string section, string key, string value)
{
lock(_lockObj)
{
WriteValue(configPath, section, key, value);
}
}
三、Nini库
1、优势
- 可直接获取数值、布尔等类型而无需手动转换;
- 支持INI/XML/注册表等多种配置源,提供统一接口;
- 通过ConfigSource.AutoSave = true实现配置变更自动持久化;
- 支持配置合并、环境变量替换、加密字段处理等场景。
2、安装与初始化
Install-Package Nini
var source = new IniConfigSource("app.ini");
IConfig config = source.Configs["Database"];
3、数据读写操作
操作类型 | 代码示例 |
---|---|
读取字符串值 | string server = config.Get(“Server”); |
写入配置 | config.Set(“Host”, “10.0.0.1”); config.Set(“Port”,3306"); source.Save(); |
敏感字段加密 | config.Set(“Password”, AesHelper.Encrypt(“123456”)); string pwd = AesHelper.Decrypt(config.Get(“Password”)); |
监听配置变更 | source.Saved += (sender, e) => { Console.WriteLine($“配置已更新:{e.FileName}”);}; |
4、性能对比
指标 | 原生API | Nini |
---|---|---|
读取10万次耗时 | ≈850ms | ≈920ms |
类型转换 | 手动转换 | 自动类型推断 |
线程安全性 | 需手动加锁 | 内置线程安全机制 |
跨平台支持 | Windows Only | 全平台兼容 |
四、启示
在万物皆JSON的时代,我们应当清醒地认识:技术选择本质是时空条件的取舍。INI教会我们:简单性本身就是一种强大的设计哲学。