分类: c#程序设计2011-11-27 20:42 4935人阅读 评论(2) 收藏 举报

在做项目过程中,有时需要保存一些简单的配置信息,可以使用xml,也可以使用INI文件。下面是C#中读取INI的方法,相信大部分朋友都使用过这种方式。
INI文件的存储方式如下,

  1. [section]
  2. key=value
  3. key=value

读取写入方法,

  1. [DllImport("kernel32")]
  2. private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
  3. [DllImport("kernel32")]
  4. private static extern int GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, StringBuilder lpReturnedString, int nSize, string lpFileName);
  5. [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
  6. private static extern uint GetPrivateProfileSection(string lpAppName, IntPtr lpReturnedString, uint nSize, string lpFileName);
  7. private static string ReadString(string section, string key, string def, string filePath)
  8. {
  9. StringBuilder temp = new StringBuilder(1024);
  10. try
  11. {
  12. GetPrivateProfileString(section, key, def, temp, 1024, filePath);
  13. }
  14. catch
  15. { }
  16. return temp.ToString();
  17. }
  18. /// <summary>
  19. /// 根据section取所有key
  20. /// </summary>
  21. /// <param name="section"></param>
  22. /// <param name="filePath"></param>
  23. /// <returns></returns>
  24. public static string[] ReadIniAllKeys(string section,string filePath)
  25. {
  26. UInt32 MAX_BUFFER = 32767;
  27. string[] items = new string[0];
  28. IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER * sizeof(char));
  29. UInt32 bytesReturned = GetPrivateProfileSection(section, pReturnedString, MAX_BUFFER, filePath);
  30. if (!(bytesReturned == MAX_BUFFER - 2) || (bytesReturned == 0))
  31. {
  32. string returnedString = Marshal.PtrToStringAuto(pReturnedString, (int)bytesReturned);
  33. items = returnedString.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
  34. }
  35. Marshal.FreeCoTaskMem(pReturnedString);
  36. return items;
  37. }
  38. /// <summary>
  39. /// 根据section,key取值
  40. /// </summary>
  41. /// <param name="section"></param>
  42. /// <param name="keys"></param>
  43. /// <param name="filePath">ini文件路径</param>
  44. /// <returns></returns>
  45. public static string ReadIniKeys(string section, string keys, string filePath)
  46. {
  47. return ReadString(section, keys, "", filePath);
  48. }
  49. /// <summary>
  50. /// 保存ini
  51. /// </summary>
  52. /// <param name="section"></param>
  53. /// <param name="key"></param>
  54. /// <param name="value"></param>
  55. /// <param name="filePath">ini文件路径</param>
  56. public static void WriteIniKeys(string section, string key, string value, string filePath)
  57. {
  58. WritePrivateProfileString(section, key, value, filePath);
  59. }

如果要删除某一项:

  1. WriteIniKeys(section, key, null, recordIniPath);

如上就可以读取和写入了,那么INI文件如何创建呢?

  1. [DllImport("kernel32")]
  2. public static extern long WritePrivateProfileString(string section, string key, string value, string iniPath);

调用该方法,即可创建你的ini文件和想要保存的值。

当然上面的ini操作并不是很详细的,以下从http://blog.csdn.net/sdfkfkd/article/details/7050733的博客转载的一片描述INI操作的,比较详细,值得学习。

  1. public class INIOperationClass
  2. {
  3. #region INI文件操作
  4. /*
  5. * 针对INI文件的API操作方法,其中的节点(Section)、键(KEY)都不区分大小写
  6. * 如果指定的INI文件不存在,会自动创建该文件。
  7. *
  8. * CharSet定义的时候使用了什么类型,在使用相关方法时必须要使用相应的类型
  9. *      例如 GetPrivateProfileSectionNames声明为CharSet.Auto,那么就应该使用 Marshal.PtrToStringAuto来读取相关内容
  10. *      如果使用的是CharSet.Ansi,就应该使用Marshal.PtrToStringAnsi来读取内容
  11. *
  12. */
  13. #region API声明
  14. /// <summary>
  15. /// 获取所有节点名称(Section)
  16. /// </summary>
  17. /// <param name="lpszReturnBuffer">存放节点名称的内存地址,每个节点之间用\0分隔</param>
  18. /// <param name="nSize">内存大小(characters)</param>
  19. /// <param name="lpFileName">Ini文件</param>
  20. /// <returns>内容的实际长度,为0表示没有内容,为nSize-2表示内存大小不够</returns>
  21. [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
  22. private static extern uint GetPrivateProfileSectionNames(IntPtr lpszReturnBuffer, uint nSize, string lpFileName);
  23. /// <summary>
  24. /// 获取某个指定节点(Section)中所有KEY和Value
  25. /// </summary>
  26. /// <param name="lpAppName">节点名称</param>
  27. /// <param name="lpReturnedString">返回值的内存地址,每个之间用\0分隔</param>
  28. /// <param name="nSize">内存大小(characters)</param>
  29. /// <param name="lpFileName">Ini文件</param>
  30. /// <returns>内容的实际长度,为0表示没有内容,为nSize-2表示内存大小不够</returns>
  31. [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
  32. private static extern uint GetPrivateProfileSection(string lpAppName, IntPtr lpReturnedString, uint nSize, string lpFileName);
  33. /// <summary>
  34. /// 读取INI文件中指定的Key的值
  35. /// </summary>
  36. /// <param name="lpAppName">节点名称。如果为null,则读取INI中所有节点名称,每个节点名称之间用\0分隔</param>
  37. /// <param name="lpKeyName">Key名称。如果为null,则读取INI中指定节点中的所有KEY,每个KEY之间用\0分隔</param>
  38. /// <param name="lpDefault">读取失败时的默认值</param>
  39. /// <param name="lpReturnedString">读取的内容缓冲区,读取之后,多余的地方使用\0填充</param>
  40. /// <param name="nSize">内容缓冲区的长度</param>
  41. /// <param name="lpFileName">INI文件名</param>
  42. /// <returns>实际读取到的长度</returns>
  43. [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
  44. private static extern uint GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, [In, Out] char[] lpReturnedString, uint nSize, string lpFileName);
  45. //另一种声明方式,使用 StringBuilder 作为缓冲区类型的缺点是不能接受\0字符,会将\0及其后的字符截断,
  46. //所以对于lpAppName或lpKeyName为null的情况就不适用
  47. [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
  48. private static extern uint GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, StringBuilder lpReturnedString, uint nSize, string lpFileName);
  49. //再一种声明,使用string作为缓冲区的类型同char[]
  50. [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
  51. private static extern uint GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, string lpReturnedString, uint nSize, string lpFileName);
  52. /// <summary>
  53. /// 将指定的键值对写到指定的节点,如果已经存在则替换。
  54. /// </summary>
  55. /// <param name="lpAppName">节点,如果不存在此节点,则创建此节点</param>
  56. /// <param name="lpString">Item键值对,多个用\0分隔,形如key1=value1\0key2=value2
  57. /// <para>如果为string.Empty,则删除指定节点下的所有内容,保留节点</para>
  58. /// <para>如果为null,则删除指定节点下的所有内容,并且删除该节点</para>
  59. /// </param>
  60. /// <param name="lpFileName">INI文件</param>
  61. /// <returns>是否成功写入</returns>
  62. [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
  63. [return: MarshalAs(UnmanagedType.Bool)]     //可以没有此行
  64. private static extern bool WritePrivateProfileSection(string lpAppName, string lpString, string lpFileName);
  65. /// <summary>
  66. /// 将指定的键和值写到指定的节点,如果已经存在则替换
  67. /// </summary>
  68. /// <param name="lpAppName">节点名称</param>
  69. /// <param name="lpKeyName">键名称。如果为null,则删除指定的节点及其所有的项目</param>
  70. /// <param name="lpString">值内容。如果为null,则删除指定节点中指定的键。</param>
  71. /// <param name="lpFileName">INI文件</param>
  72. /// <returns>操作是否成功</returns>
  73. [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  74. [return: MarshalAs(UnmanagedType.Bool)]
  75. private static extern bool WritePrivateProfileString(string lpAppName, string lpKeyName, string lpString, string lpFileName);
  76. #endregion
  77. #region 封装
  78. /// <summary>
  79. /// 读取INI文件中指定INI文件中的所有节点名称(Section)
  80. /// </summary>
  81. /// <param name="iniFile">Ini文件</param>
  82. /// <returns>所有节点,没有内容返回string[0]</returns>
  83. public static string[] INIGetAllSectionNames(string iniFile)
  84. {
  85. uint MAX_BUFFER = 32767;    //默认为32767
  86. string[] sections = new string[0];      //返回值
  87. //申请内存
  88. IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER * sizeof(char));
  89. uint bytesReturned = INIOperationClass.GetPrivateProfileSectionNames(pReturnedString, MAX_BUFFER, iniFile);
  90. if (bytesReturned != 0)
  91. {
  92. //读取指定内存的内容
  93. string local = Marshal.PtrToStringAuto(pReturnedString, (int)bytesReturned).ToString();
  94. //每个节点之间用\0分隔,末尾有一个\0
  95. sections = local.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
  96. }
  97. //释放内存
  98. Marshal.FreeCoTaskMem(pReturnedString);
  99. return sections;
  100. }
  101. /// <summary>
  102. /// 获取INI文件中指定节点(Section)中的所有条目(key=value形式)
  103. /// </summary>
  104. /// <param name="iniFile">Ini文件</param>
  105. /// <param name="section">节点名称</param>
  106. /// <returns>指定节点中的所有项目,没有内容返回string[0]</returns>
  107. public static string[] INIGetAllItems(string iniFile, string section)
  108. {
  109. //返回值形式为 key=value,例如 Color=Red
  110. uint MAX_BUFFER = 32767;    //默认为32767
  111. string[] items = new string[0];      //返回值
  112. //分配内存
  113. IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER * sizeof(char));
  114. uint bytesReturned = INIOperationClass.GetPrivateProfileSection(section, pReturnedString, MAX_BUFFER, iniFile);
  115. if (!(bytesReturned == MAX_BUFFER - 2) || (bytesReturned == 0))
  116. {
  117. string returnedString = Marshal.PtrToStringAuto(pReturnedString, (int)bytesReturned);
  118. items = returnedString.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
  119. }
  120. Marshal.FreeCoTaskMem(pReturnedString);     //释放内存
  121. return items;
  122. }
  123. /// <summary>
  124. /// 获取INI文件中指定节点(Section)中的所有条目的Key列表
  125. /// </summary>
  126. /// <param name="iniFile">Ini文件</param>
  127. /// <param name="section">节点名称</param>
  128. /// <returns>如果没有内容,反回string[0]</returns>
  129. public static string[] INIGetAllItemKeys(string iniFile, string section)
  130. {
  131. string[] value = new string[0];
  132. const int SIZE = 1024 * 10;
  133. if (string.IsNullOrEmpty(section))
  134. {
  135. throw new ArgumentException("必须指定节点名称", "section");
  136. }
  137. char[] chars = new char[SIZE];
  138. uint bytesReturned = INIOperationClass.GetPrivateProfileString(section, null, null, chars, SIZE, iniFile);
  139. if (bytesReturned != 0)
  140. {
  141. value = new string(chars).Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
  142. }
  143. chars = null;
  144. return value;
  145. }
  146. /// <summary>
  147. /// 读取INI文件中指定KEY的字符串型值
  148. /// </summary>
  149. /// <param name="iniFile">Ini文件</param>
  150. /// <param name="section">节点名称</param>
  151. /// <param name="key">键名称</param>
  152. /// <param name="defaultValue">如果没此KEY所使用的默认值</param>
  153. /// <returns>读取到的值</returns>
  154. public static string INIGetStringValue(string iniFile, string section, string key, string defaultValue)
  155. {
  156. string value = defaultValue;
  157. const int SIZE = 1024 * 10;
  158. if (string.IsNullOrEmpty(section))
  159. {
  160. throw new ArgumentException("必须指定节点名称", "section");
  161. }
  162. if (string.IsNullOrEmpty(key))
  163. {
  164. throw new ArgumentException("必须指定键名称(key)", "key");
  165. }
  166. StringBuilder sb = new StringBuilder(SIZE);
  167. uint bytesReturned = INIOperationClass.GetPrivateProfileString(section, key, defaultValue, sb, SIZE, iniFile);
  168. if (bytesReturned != 0)
  169. {
  170. value = sb.ToString();
  171. }
  172. sb = null;
  173. return value;
  174. }
  175. /// <summary>
  176. /// 在INI文件中,将指定的键值对写到指定的节点,如果已经存在则替换
  177. /// </summary>
  178. /// <param name="iniFile">INI文件</param>
  179. /// <param name="section">节点,如果不存在此节点,则创建此节点</param>
  180. /// <param name="items">键值对,多个用\0分隔,形如key1=value1\0key2=value2</param>
  181. /// <returns></returns>
  182. public static bool INIWriteItems(string iniFile, string section, string items)
  183. {
  184. if (string.IsNullOrEmpty(section))
  185. {
  186. throw new ArgumentException("必须指定节点名称", "section");
  187. }
  188. if (string.IsNullOrEmpty(items))
  189. {
  190. throw new ArgumentException("必须指定键值对", "items");
  191. }
  192. return INIOperationClass.WritePrivateProfileSection(section, items, iniFile);
  193. }
  194. /// <summary>
  195. /// 在INI文件中,指定节点写入指定的键及值。如果已经存在,则替换。如果没有则创建。
  196. /// </summary>
  197. /// <param name="iniFile">INI文件</param>
  198. /// <param name="section">节点</param>
  199. /// <param name="key">键</param>
  200. /// <param name="value">值</param>
  201. /// <returns>操作是否成功</returns>
  202. public static bool INIWriteValue(string iniFile, string section, string key, string value)
  203. {
  204. if (string.IsNullOrEmpty(section))
  205. {
  206. throw new ArgumentException("必须指定节点名称", "section");
  207. }
  208. if (string.IsNullOrEmpty(key))
  209. {
  210. throw new ArgumentException("必须指定键名称", "key");
  211. }
  212. if (value == null)
  213. {
  214. throw new ArgumentException("值不能为null", "value");
  215. }
  216. return INIOperationClass.WritePrivateProfileString(section, key, value, iniFile);
  217. }
  218. /// <summary>
  219. /// 在INI文件中,删除指定节点中的指定的键。
  220. /// </summary>
  221. /// <param name="iniFile">INI文件</param>
  222. /// <param name="section">节点</param>
  223. /// <param name="key">键</param>
  224. /// <returns>操作是否成功</returns>
  225. public static bool INIDeleteKey(string iniFile, string section, string key)
  226. {
  227. if (string.IsNullOrEmpty(section))
  228. {
  229. throw new ArgumentException("必须指定节点名称", "section");
  230. }
  231. if (string.IsNullOrEmpty(key))
  232. {
  233. throw new ArgumentException("必须指定键名称", "key");
  234. }
  235. return INIOperationClass.WritePrivateProfileString(section, key, null, iniFile);
  236. }
  237. /// <summary>
  238. /// 在INI文件中,删除指定的节点。
  239. /// </summary>
  240. /// <param name="iniFile">INI文件</param>
  241. /// <param name="section">节点</param>
  242. /// <returns>操作是否成功</returns>
  243. public static bool INIDeleteSection(string iniFile, string section)
  244. {
  245. if (string.IsNullOrEmpty(section))
  246. {
  247. throw new ArgumentException("必须指定节点名称", "section");
  248. }
  249. return INIOperationClass.WritePrivateProfileString(section, null, null, iniFile);
  250. }
  251. /// <summary>
  252. /// 在INI文件中,删除指定节点中的所有内容。
  253. /// </summary>
  254. /// <param name="iniFile">INI文件</param>
  255. /// <param name="section">节点</param>
  256. /// <returns>操作是否成功</returns>
  257. public static bool INIEmptySection(string iniFile, string section)
  258. {
  259. if (string.IsNullOrEmpty(section))
  260. {
  261. throw new ArgumentException("必须指定节点名称", "section");
  262. }
  263. return INIOperationClass.WritePrivateProfileSection(section, string.Empty, iniFile);
  264. }
  265. private void TestIniINIOperation()
  266. {
  267. string file = "F:\\TestIni.ini";
  268. //写入/更新键值
  269. INIWriteValue(file, "Desktop", "Color", "Red");
  270. INIWriteValue(file, "Desktop", "Width", "3270");
  271. INIWriteValue(file, "Toolbar", "Items", "Save,Delete,Open");
  272. INIWriteValue(file, "Toolbar", "Dock", "True");
  273. //写入一批键值
  274. INIWriteItems(file, "Menu", "File=文件\0View=视图\0Edit=编辑");
  275. //获取文件中所有的节点
  276. string[] sections = INIGetAllSectionNames(file);
  277. //获取指定节点中的所有项
  278. string[] items = INIGetAllItems(file, "Menu");
  279. //获取指定节点中所有的键
  280. string[] keys = INIGetAllItemKeys(file, "Menu");
  281. //获取指定KEY的值
  282. string value = INIGetStringValue(file, "Desktop", "color", null);
  283. //删除指定的KEY
  284. INIDeleteKey(file, "desktop", "color");
  285. //删除指定的节点
  286. INIDeleteSection(file, "desktop");
  287. //清空指定的节点
  288. INIEmptySection(file, "toolbar");
  289. }
  290. #endregion
  291. #endregion
  292. }

原文引入:http://blog.csdn.net/yysyangyangyangshan/article/details/7017523?reload

C#如何读写和创建INI文件(经典)转的更多相关文章

  1. C#如何读写和创建INI文件

    在做项目过程中,有时需要保存一些简单的配置信息,可以使用xml,也可以使用INI文件.下面是C#中读取INI的方法,相信大部分朋友都使用过这种方式.INI文件的存储方式如下, [section] ke ...

  2. C# 创建INI文件,写入并可读取。----转载

    基于C#winform设计. 首先创建一个类,我命名为IniFiles.并引入命名空间using System.Runtime.InteropServices; 接着,声明API函数 [DllImpo ...

  3. IDEA中怎么创建ini文件

    首先博主在这使用的是idea的2019.3.2的版本,不知道的话可以打开help菜单的about查看 第一步: 具体需要在setings安装ini插件 第二步: 在File Types中查看ini,没 ...

  4. pycharm新建ini文件或创建ini文件失败

    1.pycharm创建ini格式的文件,没有对应的 ini 文件类型-------需要更新 Ini 2.setting–>marketplace 搜索 Ini ,然后进行安装,重启pycharm ...

  5. C#中读写INI文件

    INI文件就是扩展名为“ini”的文件.在Windows系统中,INI文件是很多,最重要的就是“System.ini”.“System32.ini”和“Win.ini”.该文件主要存放用户所做的选择以 ...

  6. 如何在C#中读写INI文件

    INI文件就是扩展名为"ini"的文件.在Windows系统中,INI文件是很多,最重要的就是"System.ini"."System32.ini&q ...

  7. delphi读取ini文件

    ini文件在系统配置及应用程序参数保存与设置方面,具有很重要的作用,所以可视化的编程一族,如vb.vc.vfp.delphi等都提供了读写ini文件的方法,其中delphi中操作ini文件,最为简洁, ...

  8. delphi INI文件

    INI 文件读写 filecreate('路径加文件名')://创建一个文件. (1) INI文件的结构: ;这是关于INI文件的注释部分 [节点] 关键字=值 ... INI文件允许有多个节点,每个 ...

  9. 创建Unicode格式的INI文件

    前段时间由于开发一个软件,需要调用别人的接口,虽然我的软件是Unicode编码,对方的模块也是Unicode编码,但是对方提供的接口却是Ansi接口,在非中文系统下,由于涉及到中文路径,导致Ansi和 ...

随机推荐

  1. http服务器与https服务器的区别

    1.HTTPS服务器使用的是HTTPS协议,而HTTP使用的是HTTP协议. 2.HTTPS服务器需要向证书授权中心申请证书,一般免费证书很少,需要交费. 3.HTTP服务器与客户端传递的是明文数据, ...

  2. shouldComponentUpdate不能直接比较object

    凡是参阅过react官方英文文档的童鞋大体上都能知道对于一个组件来说,其state的改变(调用this.setState()方法)以及从父组件接受的props发生变化时,会导致组件重渲染,正所谓&qu ...

  3. Day 13 进程和线程

    进程和线程 今天我们使用的计算机早已进入多CPU或多核时代,而我们使用的操作系统都是支持“多任务”的操作系统,这使得我们可以同时运行多个程序,也可以将一个程序分解为若干个相对独立的子任务,让多个子任务 ...

  4. sublime右键菜单,anaconda设置

    1.sublime_addright.inf [Version]Signature="$Windows NT$" [DefaultInstall]AddReg=SublimeTex ...

  5. Django - 数据获取

    Django - 数据获取 1.radio值获取 2.checkbox获取 3.select 获取 select 获取值,需要根据前端multiple来获取,get or getlist; 4.上传文 ...

  6. BFS入门篇——RQNOJ195&&335

    PID195 / 校园迷宫☆ 从x,y走到去q,w的最小步数,限制是有的点可走,有的点不可走,BFS嘛. #include<bits/stdc++.h> using namespace s ...

  7. mysql5.7 简易修改mysql密码

    MySQL 5.7 mysql库的user表中已经不再有password字段,取而代之的为authentication_string修改语法相同,步骤也相同.注意:/etc/my.cnf这个配置文件中 ...

  8. Train Problem II HDU 1023 卡特兰数

    Problem Description As we all know the Train Problem I, the boss of the Ignatius Train Station want ...

  9. Spring MVC 一次简单的 CRUD

    基本环境搭建 1.数据库 和 实体类 的名字相同,实体类 属性名即 数据库 字段名. 2.创建 实体类 对应 dao 类,持久层框架 mybatis 正处于学习中,这里就用原始的 jdbc 操作了. ...

  10. Linxu用户管理(转)

    说明:用户管理的操作涉及root权限,所以以下实例中应该使用sudo或者root用户进行操作. 背景: Linux系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管 ...