在C#应用程序中,常将INI文件作为配置文件,用于存储应用程序的设置和参数。
一、INI文件结构
INI文件结构简单,由节(Sections)和键值对(Key-Value Pairs)组成。每个节由方括号包围,例如[SectionName],而键值对则是以等号=分隔的字符串,例如Key=Value。每个节都包含一个或多个键值对,用于存储相关的配置信息。
INI文件示例:
[AmplifierForm]
ResInitialize=0.5,0.7,0.5,0.6,0.6
[OffSignalForm]
ResInitialize=0.5,0.7,0.5,0.6,0.6
ResColl=1.3,1.5
该示例中有两个节:AmplifierForm、OffSignalForm,每个节下都有一些键值对,用于存储配置信息。
二、读取INI文件中的数据
C#命名空间中没有直接读写INI的类,但在"kernel32.dll"文件中有Win32的API函数–WritePrivateProfileString()和GetPrivateProfileString(),可操作ini文件。
静态操作使用类
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace FileOperationsDemo
{
public class ReadWriteINI
{
#region API函数声明
/// <summary>
/// 写入ini文件
/// </summary>
/// <param name="section">节点名称</param>
/// <param name="key">键</param>
/// <param name="val">值</param>
/// <param name="filePath">ini路径</param>
/// <returns>0失败/其他成功</returns>
[DllImport("kernel32")]
private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
/// <summary>
///
/// </summary>
/// <param name="section">节点名称,[]内的段落名</param>
/// <param name="key">键</param>
/// <param name="def">值(未读取到数据时设置的默认返回值)</param>
/// 对应API函数的def参数,它的值由用户指定,是当在配置文件中没有找到具体的Value时,就用def的值来代替。可以为空
/// <param name="retVal">读取到的结果值</param>
/// <param name="size">读取缓冲区大小</param>
/// <param name="filePath">ini配置文件的路径加ini文件名</param>
/// <returns>读取到的字节数量</returns>
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
#endregion
/// <summary>
/// 写INI,添加新节点、键值,及编辑修改键对应的值
/// </summary>
/// <param name="in_filename">ini配置文件的路径加ini文件名</param>
/// <param name="Section">节点名称,[]内的段落名</param>
/// <param name="Key">键</param>
/// <param name="Value">值</param>
public static bool IniFile_SetVal(string in_filename, string Section, string Key, string Value)
{
if (File.Exists(in_filename))
{
// 调用winapi函数将Key=Value写入Section节点下
long len = WritePrivateProfileString(Section, Key, Value, in_filename);
if (len == 0)
{
return false;
}
else
{
return true;
}
}
else
{
return true;
}
}
/// <summary>
/// 读ini
/// </summary>
/// <param name="in_filename">ini配置文件的路径加ini文件名</param>
/// <param name="Section">节点名称,[]内的段落名</param>
/// <param name="Key">键</param>
/// <returns></returns>
public static string IniFile_GetVal(string in_filename, string Section, string Key)
{
if (File.Exists(in_filename))
{
// 声明接收的数据
StringBuilder builder = new StringBuilder(1024);
// 调用winapi函数读取Section节点下Key的值
int len = GetPrivateProfileString(Section, Key, "", builder, 1024, in_filename);
if (len == 0)
return "1";
else
return (builder.ToString());
}
else
return string.Empty;
}
}
}
操作示例
/// <summary>
/// 读取ini文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button3_Click(object sender, EventArgs e)
{
string pathName = Application.StartupPath + "\\config\\ResOriginal.ini";
string resStarter = ReadWriteINI.IniFile_GetVal(pathName, "SelfCheckFace", "ResInitialize");
string[] resInitLine = resStarter.Split(',');
for (int ii = 0; ii < resInitLine.Length; ii++)
{
richTextBox2.AppendText(resInitLine[ii] + "\n");
}
}
/// <summary>
/// 写入ini文件,新建或编辑
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button4_Click(object sender, EventArgs e)
{
string pathName = Application.StartupPath + "\\config\\ResOriginal.ini";
ReadWriteINI.IniFile_SetVal(pathName, "SelfCheckFace", "ResInitialize", "1,2,3,4,5");
string[] resInitLine = richTextBox2.Lines;
string tempWrite = string.Join(",", resInitLine);
tempWrite=tempWrite.Remove(tempWrite.Length-1);
ReadWriteINI.IniFile_SetVal(pathName, "SelfCheckF", "ResInitialize", tempWrite);
}