Ini文件在配置上还是比较傻瓜明了的,所以还是有蛮多人喜欢使用ini文件来做一些程序上的简单配置,但我发现ini文件对中文支持不好,比如Section里有中文,或者Key含有中文,等等,往往用API调用后出现乱码甚至系统干脆认为读取失败,返回默认值,网上没有解决办法,看来只能自己动手。解决的关键就是编码问题,由于网上千篇一律的API写法,几乎就是下面这样子:
class="brush:csharp;gutter:true;">[DllImport("kernel32", CharSet = CharSet.Auto)] public static extern int GetPrivateProfileString(string section, string key, string defVal, byte[] retVal, int size, string filePath);
其实正确的写法应该是:
[DllImport("kernel32")] public static extern bool WritePrivateProfileString(byte[] section, byte[] key, byte[] val, string filePath); [DllImport("kernel32")] public static extern int GetPrivateProfileString(byte[] section, byte[] key, byte[] def, byte[] retVal, int size, string filePath);
大家只要把section,key,val,def等统统指定编码getBytes(),即可完美解决编码问题
附上源码:
[DllImport("kernel32")] public static extern bool WritePrivateProfileString(byte[] section, byte[] key, byte[] val, string filePath); [DllImport("kernel32")] public static extern int GetPrivateProfileString(byte[] section, byte[] key, byte[] def, byte[] retVal, int size, string filePath); //与ini交互必须统一编码格式 private static byte[] getBytes(string s, string encodingName) { return null == s ? null : Encoding.GetEncoding(encodingName).GetBytes(s); } public static string ReadString(string section, string key, string def, string fileName, string encodingName = "utf-8", int size = 1024) { byte[] buffer = new byte[size]; int count = GetPrivateProfileString( getBytes(section, encodingName), getBytes(key, encodingName), getBytes(def, encodingName), buffer, size, fileName); return Encoding.GetEncoding(encodingName).GetString(buffer, 0, count).Trim(); } public static bool WriteString(string section, string key, string value, string fileName, string encodingName="utf-8") { return WritePrivateProfileString( getBytes(section, encodingName), getBytes(key, encodingName), getBytes(value, encodingName), fileName); }
其他诸如删除节点等等,大家应该都会举一反三,此处就略去了,有了它,管他UTF-8还是汉字日文爪哇文,统统不在话下!本文属原创,转载请注明出处,谢谢
另外我个人还有个疑问,ini文件第一行不能被识别,也就是第一行不能输入有效信息,否则会导致无法读取到某些内容的现象发生,不知道是bug还是其他原因,希望有大神指教。