C#读写ini文件

打印 上一主题 下一主题

主题 1016|帖子 1016|积分 3048

C#读写ini文件

调用winAPI 实现ini文件操作

  • dll路径:C:\Windows\System32\kernel32.dll;
  • 若调用失败可查看dll是否存在以及环境变量(C:\Windows\System32)是否已设置
  • 静态类编写如下
    文件接纳默认路径,若需要改变,调用之前请先更新文件路径
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Runtime.InteropServices;
  7. namespace BasicExercises
  8. {
  9.     /***
  10.      *  ini文件样式
  11.      *  [配置项]
  12.      *  属性1 = 属性值
  13.      *  属性2 = 属性值
  14.      *  ...
  15.      *  
  16.      *  CharSet定义的时候使用了什么类型,在使用相关方法时必须要使用相应的类型
  17.      *      例如 GetPrivateProfileSectionNames声明为CharSet.Auto,那么就应该使用 Marshal.PtrToStringAuto来读取相关内容
  18.      *      如果使用的是CharSet.Ansi,就应该使用Marshal.PtrToStringAnsi来读取内容
  19.      * **/
  20.     class IniConfigHelper
  21.     {
  22.         static string iniFilePath = Environment.CurrentDirectory+"config.ini";
  23.         public static string IniFilePath { get => iniFilePath; set => iniFilePath = value; }
  24.         /***
  25.          * 调用winAPI 实现ini文件操作
  26.          * dll路径:C:\Windows\System32\kernel32.dll,若调用失败可查看dll是否存在以及环境变量(C:\Windows\System32)是否已设置
  27.          * 以下是API函数
  28.         ***/
  29.         /// <summary>
  30.         /// 写入ini文件:将指定的键和值写到指定的节点,如果已经存在则替换
  31.         /// </summary>
  32.         /// <param name="section">节点名称</param>
  33.         /// <param name="key">键,null也直接写入</param>
  34.         /// <param name="value">值,null也直接写入</param>
  35.         /// <param name="filePath">ini文件路径</param>
  36.         /// <returns>0失败/其他成功</returns>
  37.         //[DllImport("kernel32", CharSet = CharSet.Auto)]
  38.         //private static extern long WritePrivateProfileString(string section, string key, string value, string filePath);
  39.         /// <summary>
  40.         /// 写入ini文件:将指定的键和值写到指定的节点,如果已经存在则替换
  41.         /// </summary>
  42.         /// <param name="section">节点名称</param>
  43.         /// <param name="key">键,null则删除指定的节点及其所有的项目</param>
  44.         /// <param name="value">值,null则删除指定节点中指定的键</param>
  45.         /// <param name="filePath">ini文件路径</param>
  46.         /// <returns>操作是否成功</returns>
  47.         [DllImport("kernel32", CharSet = CharSet.Auto)]
  48.         private static extern bool WritePrivateProfileString(string section, string key, string value, string filePath);
  49.         /// <summary>
  50.         /// 将指定的键值对写到指定的节点,如果已经存在则替换。
  51.         /// </summary>
  52.         /// <param name="section">节点,如果不存在此节点,则创建此节点</param>
  53.         /// <param name="keyValue">Item键值对,多个用\0分隔,形如key1=value1\0key2=value2
  54.         ///     如果为string.Empty,则删除指定节点下的所有内容,保留节点
  55.         ///     如果为null,则删除指定节点下的所有内容,并且删除该节点
  56.         ///     该方法无脑写入,遇"\0"换行写入
  57.         /// </param>
  58.         /// <param name="filePath"></param>
  59.         /// <returns>操作成功与否</returns>
  60.         [DllImport("kernel32", CharSet = CharSet.Auto)]
  61.         private static extern bool WritePrivateProfileSection(string section, string keyValue, string filePath);
  62.         /// <summary>
  63.         /// 调用winAPI读取ini文件
  64.         /// </summary>
  65.         /// <param name="section">节点名称</param>
  66.         /// <param name="key">键</param>
  67.         /// <param name="def">值(未读取到数据时设置的默认返回值)</param>
  68.         /// <param name="result">读取的结构值</param>
  69.         /// <param name="size">读取的缓冲区大小</param>
  70.         /// <param name="filePath">ini路径</param>
  71.         /// <returns>读取到的字节数量</returns>
  72.         [DllImport("kernel32", CharSet = CharSet.Auto)]
  73.         private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder result, int size, string filePath);
  74.         /// <summary>
  75.         /// 获取所有节点名称(Section)
  76.         /// </summary>
  77.         /// <param name="ptrResultBuffer">存放节点名称的内存地址,每个节点之间使用\0分隔</param>
  78.         /// <param name="nSize">内存大小</param>
  79.         /// <param name="filePath">ini文件路径</param>
  80.         /// <returns>内容的实际长度,为0表示没有内容,为nSize-2表示内存大小不够</returns>
  81.         [DllImport("kernel32", CharSet = CharSet.Auto)]
  82.         private static extern uint GetPrivateProfileSectionsNames(IntPtr lpResultBuffer,uint nSize,string filePath);
  83.         /// <summary>
  84.         /// 获取某个指定节点(Section)中所有KEY和Value
  85.         /// </summary>
  86.         /// <param name="section">节点名称</param>
  87.         /// <param name="lpReturnedString">返回值的内存地址,每个之间使用\0分隔</param>
  88.         /// <param name="nSize">内存大小</param>
  89.         /// <param name="filePath">ini文件地址</param>
  90.         /// <returns></returns>
  91.         [DllImport("kernel32", CharSet = CharSet.Auto)]
  92.         private static extern uint GetPrivateProfileSection(string section, IntPtr lpReturnedString, uint nSize, string filePath);
  93.         /***
  94.          * 调用winAPI 实现ini文件操作
  95.          * 以下是API对应的调用函数封装
  96.         ***/
  97.         /// <summary>
  98.         /// 写入ini,指定节点下单键值对写入
  99.         /// </summary>
  100.         /// <param name="section"></param>
  101.         /// <param name="key"></param>
  102.         /// <param name="value"></param>
  103.         /// <returns>操作成功与否</returns>
  104.         public static bool  WriteToIni(string section, string key, string value)
  105.         {
  106.             if (string.IsNullOrEmpty(section))
  107.             {
  108.                 return false;
  109.                 //throw new ArgumentException("必须指定节点名称",section);
  110.             }
  111.             if (string.IsNullOrEmpty(key))
  112.             {
  113.                 return false;
  114.                 //throw new ArgumentException("必须指定key值",key);
  115.             }
  116.             if (string.IsNullOrEmpty(value))
  117.             {
  118.                 return false;
  119.                 //throw new ArgumentException("值不能为空",value);
  120.             }
  121.             return WritePrivateProfileString(section, key, value, iniFilePath);
  122.         }
  123.         /// <summary>
  124.         /// 删除指定节点下指定键
  125.         /// </summary>
  126.         /// <param name="section">节点</param>
  127.         /// <param name="key">键</param>
  128.         /// <returns>操作成功与否</returns>
  129.         public static bool DeleteKey(string section, string key)
  130.         {
  131.             if (string.IsNullOrEmpty(section))
  132.             {
  133.                 return false;
  134.                 //throw new ArgumentException("必须指定节点名称",section);
  135.             }
  136.             if (string.IsNullOrEmpty(key))
  137.             {
  138.                 return false;
  139.                 //throw new ArgumentException("必须指定key值",key);
  140.             }
  141.             return WritePrivateProfileString(section, key, null, iniFilePath);
  142.         }
  143.         /// <summary>
  144.         /// 删除指定节点
  145.         /// </summary>
  146.         /// <param name="section">节点</param>
  147.         /// <returns>操作成功与否</returns>
  148.         public static bool DeleteSection(string section)
  149.         {
  150.             if (string.IsNullOrEmpty(section))
  151.             {
  152.                 return false;
  153.                 //throw new ArgumentException("必须指定节点名称",section);
  154.             }
  155.             return WritePrivateProfileString(section, null, null, iniFilePath);
  156.         }
  157.         /// <summary>
  158.         /// 清空指定节点
  159.         /// </summary>
  160.         /// <param name="section">节点</param>
  161.         /// <returns>操作成功与否</returns>
  162.         public  static  bool EmptySection(string section)
  163.         {
  164.             if (string.IsNullOrEmpty(section))
  165.             {
  166.                 return false;
  167.                 //throw new ArgumentException("必须指定节点名称",section);
  168.             }
  169.             return WritePrivateProfileSection(section,string.Empty,iniFilePath);
  170.         }
  171.         /// <summary>
  172.         /// 写入ini,指定节点下多个键值对写入
  173.         /// </summary>
  174.         /// <param name="section">节点</param>
  175.         /// <param name="keyValue">键值对,形如key1=value1\0key2=value2 </param>
  176.         /// <returns></returns>
  177.         public static bool WriteToIniSection(string section, string keyValue)
  178.         {
  179.             if (string.IsNullOrEmpty(section))
  180.             {
  181.                 return false;
  182.                 //throw new ArgumentException("必须指定节点名称",section);
  183.             }
  184.             if (string.IsNullOrEmpty(keyValue))
  185.             {
  186.                 return false;
  187.                 //throw new ArgumentException("键值对不能为空",keyValue);
  188.             }
  189.             return WritePrivateProfileSection(section, keyValue, iniFilePath);
  190.         }
  191.       
  192.         /// <summary>
  193.         /// 读取ini,section和key不能为null
  194.         /// </summary>
  195.         /// <param name="section">节点</param>
  196.         /// <param name="key">键</param>
  197.         /// <returns>null或读取结果</returns>
  198.         public static string ReadFromIni(string section,string key)
  199.         {
  200.             if (string.IsNullOrEmpty(section))
  201.             {
  202.                 return null;
  203.                 //throw new ArgumentException("必须指定节点名称", section);
  204.             }
  205.             if (string.IsNullOrEmpty(key))
  206.             {
  207.                 return null;
  208.                 //throw new ArgumentException("必须指定key值", key);
  209.             }
  210.             int size = 1024;
  211.             StringBuilder builder = new StringBuilder(size);
  212.             //string def = "";
  213.             int result = GetPrivateProfileString(section, key, "", builder, size, iniFilePath);
  214.             return builder.ToString();
  215.         }
  216.         /// <summary>
  217.         /// 获取ini文件所有节点
  218.         /// </summary>
  219.         /// <returns>所有节点,没有内容返回string[0]</returns>
  220.         public static string[] GetAllSections()
  221.         {
  222.             uint MAX_BUFFER = 32767;
  223.             string[] sections = new string[0];
  224.             //申请内存
  225.             IntPtr pReturnedStr = Marshal.AllocCoTaskMem((int)MAX_BUFFER * sizeof(char));
  226.             //读取内容
  227.             uint nSize = GetPrivateProfileSectionsNames(pReturnedStr, MAX_BUFFER, iniFilePath);
  228.             if (nSize != 0 && nSize != MAX_BUFFER - 2)
  229.             {
  230.                 //读取内存内存
  231.                 string returnedStr = Marshal.PtrToStringAuto(pReturnedStr, (int)nSize);
  232.                 //转换成string[]格式
  233.                 sections = returnedStr.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
  234.             }
  235.             //释放内存
  236.             Marshal.FreeCoTaskMem(pReturnedStr);
  237.             return sections;
  238.         }
  239.         /// <summary>
  240.         /// 获取指定节点下的所有key、value;形式key=value
  241.         /// </summary>
  242.         /// <param name="section">指定节点</param>
  243.         /// <returns>指定节点的所有条目,空则返回string[0]</returns>
  244.         public static string[] GetAllKeyValueBySection(string section)
  245.         {
  246.             if (string.IsNullOrEmpty(section))
  247.             {
  248.                 return null;
  249.                 //throw new ArgumentException("必须指定节点名称", section);
  250.             }
  251.             uint MAX_BUFFER = 32767;
  252.             string[] items = new string[0];
  253.             //分配内存
  254.             IntPtr pReturnedStr = Marshal.AllocCoTaskMem((int)MAX_BUFFER * sizeof(char));
  255.             uint nSize = GetPrivateProfileSection(section, pReturnedStr, MAX_BUFFER, iniFilePath);
  256.             if (nSize != 0 && nSize != MAX_BUFFER - 2)
  257.             {
  258.                 //读取内存内容
  259.                 string returnedStr = Marshal.PtrToStringAuto(pReturnedStr, (int)nSize);
  260.                 每个节点之间用\0分隔,末尾有一个\0
  261.                 items = returnedStr.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
  262.             }
  263.             //释放内存
  264.             Marshal.FreeCoTaskMem(pReturnedStr);
  265.             return items;
  266.         }
  267.     }
  268. }
复制代码

  • 调用窗口:
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading;
  9. using System.Threading.Tasks;
  10. using System.Windows.Forms;
  11. namespace BasicExercises
  12. {
  13.     public partial class TestForm : Form
  14.     {
  15.         public TestForm()
  16.         {
  17.             InitializeComponent();
  18.         }
  19.         private void btnTestIni_Click(object sender, EventArgs e)
  20.         {
  21.             
  22.             string userSection = "用户";
  23.             string userNameKey = "Name";
  24.             string testSection = "测试节点";
  25.             string keyValue = "用户1=苏\0密码=苏\0用户2=林\0密码=林";
  26.             //ini写入
  27.             txtBoxMsg.Text = "";
  28.             txtBoxMsg.Text += "测试写入以下内容:\r\n[" + userSection + "]\r\n" + userNameKey + " = 测试用户";
  29.             bool IsWriteSec = IniConfigHelper.WriteToIni(userSection, userNameKey, "测试用户");
  30.             if (IsWriteSec)
  31.             {
  32.                 txtBoxMsg.Text += "\r\n写入成功!";
  33.             }
  34.             //多个键值对写入
  35.             // \0 在C#中代表结束字符,不会被窗体输出
  36.             txtBoxMsg.Text += "\r\n" + keyValue;
  37.             IsWriteSec = IniConfigHelper.WriteToIniSection(testSection, keyValue);
  38.             if (IsWriteSec)
  39.             {
  40.                 txtBoxMsg.Text += "\r\n写入成功!";
  41.             }
  42.             //ini读取指定键
  43.             string value = IniConfigHelper.ReadFromIni(userSection, userNameKey);
  44.             txtBoxMsg.Text += "\r\n读取结果:" + value;
  45.             //获取ini所有节点
  46.             string[] sectionItems = IniConfigHelper.GetAllKeyValueBySection(testSection);
  47.             string allSection = "";
  48.             foreach (string item in sectionItems)
  49.             {
  50.                 allSection += item;
  51.             }
  52.             txtBoxMsg.Text += "\r\n获取ini所有节点:" + allSection;
  53.             //获取ini指定节点下的所有key和value
  54.             string[] items = IniConfigHelper.GetAllKeyValueBySection(testSection);
  55.             string msg = "";
  56.             foreach (string item in items)
  57.             {
  58.                 msg += item;
  59.             }
  60.             txtBoxMsg.Text += "\r\n获取ini指定节点下的所有key和value:" + msg;
  61.             //删除指定key
  62.             IsWriteSec = IniConfigHelper.DeleteKey(userSection, userNameKey);
  63.             if (IsWriteSec)
  64.             {
  65.                 txtBoxMsg.Text += "\r\n删除" + "[" + userSection + "]下的键:" + userNameKey + "成功";
  66.             }
  67.             //删除指定节点
  68.             IsWriteSec = IniConfigHelper.DeleteSection(userSection);
  69.             if (IsWriteSec)
  70.             {
  71.                 txtBoxMsg.Text += "\r\n删除" + "[" + userSection + "]节点成功";
  72.             }
  73.             IsWriteSec = IniConfigHelper.DeleteSection(testSection);
  74.             if (IsWriteSec)
  75.             {
  76.                 txtBoxMsg.Text += "\r\n删除" + "[" + testSection + "]节点成功";
  77.             }
  78.         }
  79.     }
  80. }
复制代码


  • 运行结果:


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

知者何南

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表