INI文件操作类
- 格式:doc
- 大小:104.00 KB
- 文档页数:14
IniFile Ini操作分类:Delphi 2010-07-10 22:24 903人阅读评论(0) 收藏举报INI文件的结构如下[小节名]关键字=值uses IniFiles; {操作Ini文件需要引用TIniFile 的单元}常用的方法WriteString 写入字符串WriteInteger 写入数字WriteBool 写入布尔值ReadString 读取字符串值ReadInteger 读取数字ReadBool 读取布尔值ReadSections 读取小节列表ReadSection 读取某小节下关键字列表ReadSectionValues 读取某小节下所有内容列表,包括关键字和值写入view plaincopy to clipboardprint? .........10........20........30........40........50........60........70........80........90........100.......110.......120.......130.......140. (150)varF:TIniFile;beginF := TIniFile.Create('c:/A.ini'); //如果文件存在则打开,如果不存在,当向其中写入数据时,将创建ini文件F.WriteString('PersonInfo','姓名','张三');F.WriteInteger('PersonInfo','年龄',20);F.WriteBool('PersonInfo','婚否',False);end;varF:TIniFile;beginF := TIniFile.Create('c:/A.ini'); //如果文件存在则打开,如果不存在,当向其中写入数据时,将创建ini文件F.WriteString('PersonInfo','姓名','张三');F.WriteInteger('PersonInfo','年龄',20);F.WriteBool('PersonInfo','婚否',False);end;读取:读取方法的第三个参数表示,当读取失败时,返回的结果,view plaincopy to clipboardprint?varF:TIniFile;name:string;age:Integer;merry:Boolean;beginF := TIniFile.Create('c:/A.ini');name := F.ReadString('PersonInfo','姓名','无名氏'); //当读取失败时,返回'无名氏',否则返回读取的值age := F.ReadInteger('PersonInfo','年龄',20);merry := F.ReadBool('PersonInfo','婚否',False);end;varF:TIniFile;name:string;age:Integer;merry:Boolean;beginF := TIniFile.Create('c:/A.ini');name := F.ReadString('PersonInfo','姓名','无名氏'); //当读取失败时,返回'无名氏',否则返回读取的值age := F.ReadInteger('PersonInfo','年龄',20);merry := F.ReadBool('PersonInfo','婚否',False);end;读取小节的列表view plaincopy to clipboardprint?varF:TIniFile;List:TStringList;begintryList := TStringList.Create;F := TIniFile.Create('c:/A.ini');F.ReadSections(List); //将小节依次读取到List中ShowMessage(List.Text); //显示小节列表内容finallyList.Free;F.Free;end;end;varF:TIniFile;List:TStringList;begintryList := TStringList.Create;F := TIniFile.Create('c:/A.ini');F.ReadSections(List); //将小节依次读取到List中ShowMessage(List.Text); //显示小节列表内容finallyList.Free;F.Free;end;读取某小节下的关键字列表view plaincopy to clipboardprint?varF:TIniFile;List:TStringList;begintryList := TStringList.Create;F := TIniFile.Create('c:/A.ini');F.ReadSection('PersonInfo',List); //将小节依次读取到List中ShowMessage(List.Text); //显示'PersonInfo'小节下关键字列表内容finallyList.Free;F.Free;end;end;varF:TIniFile;List:TStringList;begintryList := TStringList.Create;F := TIniFile.Create('c:/A.ini');F.ReadSection('PersonInfo',List); //将小节依次读取到List中ShowMessage(List.Text); //显示'PersonInfo'小节下关键字列表内容finallyList.Free;F.Free;end;end;读取某小节下所有内容列表,包括关键字和值view plaincopy to clipboardprint?F:TIniFile;List:TStringList;begintryList := TStringList.Create;F := TIniFile.Create('c:/A.ini');F.ReadSectionValues('PersonInfo',List); //将小节依次读取到List中ShowMessage(List.Text); //读取某小节下所有内容列表,包括关键字和值finallyList.Free;F.Free;end;end;varF:TIniFile;List:TStringList;begintryList := TStringList.Create;F := TIniFile.Create('c:/A.ini');F.ReadSectionValues('PersonInfo',List); //将小节依次读取到List中ShowMessage(List.Text); //读取某小节下所有内容列表,包括关键字和值finallyList.Free;F.Free;end;end;其它常用方法EraseSection 删除某个小节DeleteKey 删除关键字SectionExists 判断某个章节是否存在ValueExists 判断某个小节下的某个关键字是否存在本文来自CSDN博客,转载请标明出处:/bdmh/archive/2009/05/04/4147104.aspx一、INI文件的结构:; 注释[小节名]关键字=值INI文件允许有多个小节,每个小节又允许有多个关键字,“=”后面是该关键字的值。
无法打开的ini文件如何处理处理无法打开的ini文件ini文件(Initialization File)是Windows操作系统中常见的配置文件格式,用于存储应用程序的配置信息。
然而,有时候我们会遇到无法打开ini文件的情况,这可能是因为文件损坏、权限问题、文件关联错误等原因所致。
本文将介绍一些常见的处理方法,帮助您解决无法打开ini文件的困扰。
方法一:检查文件完整性首先,您可以尝试检查ini文件的完整性,确保文件没有损坏。
可以通过以下方式进行检查:1. 检查文件扩展名:确保文件的扩展名为.ini。
有时候文件扩展名可能被错误地更改或省略,导致文件无法正常打开。
2. 检查文件大小:打开文件管理器,查看文件的大小。
如果文件大小为0KB或异常小,说明文件可能已经损坏。
3. 尝试打开其他ini文件:如果您有其他正常的ini文件,可以尝试打开它们,以确认是否是当前ini文件本身的问题。
如果其他ini文件可以正常打开,那么问题可能就出在当前文件上。
方法二:更改文件权限如果您在打开ini文件时遇到了权限问题,可以尝试更改文件的权限,以便您能够正常访问和编辑文件。
下面是一些常见的步骤:1. 右键点击ini文件,选择“属性”。
2. 在“属性”对话框中,点击“安全”选项卡。
3. 点击“编辑”按钮,修改当前用户对该文件的权限,确保设置为“完全控制”或者具有足够的权限进行访问和编辑。
4. 点击“确定”按钮保存更改,并尝试重新打开ini文件。
方法三:检查关联程序如果您在尝试打开ini文件时遇到了关联程序错误,可以尝试以下方法来解决问题:1. 右键点击ini文件,选择“打开方式”。
2. 在弹出的菜单中,选择“选择默认程序”。
3. 在“打开方式”对话框中,选择适合打开ini文件的程序。
如果您不确定,可以选择记事本或者其他文本编辑器。
4. 勾选“始终使用选定的程序打开此类文件”选项。
5. 点击“确定”按钮保存更改,并尝试重新打开ini文件。
ini文件只知道节名,读取节下所有值的方法qt1.引言1.1 概述概述INI文件是一种常见的配置文件格式,它被广泛用于存储和管理应用程序的配置信息。
INI文件由一系列的节(section)和键值对(key-value)组成。
每个节包含一组相关的键值对,用来描述特定的配置项。
在读取INI 文件时,通常可以根据节名和键名来获取对应的值。
然而,在某些情况下,我们可能只知道节的名称,而不清楚该节下有哪些键值对。
本文将介绍如何通过Qt框架提供的方法来读取INI文件中某个节下的所有键值对。
首先,我们需要了解Qt框架中关于INI文件的相关类和函数。
Qt提供了一个名为QSettings的类,它是用于读写配置信息的工具类。
QSettings类支持INI文件格式,并提供了方便的方法来读取和写入INI 文件中的配置项。
在使用QSettings类读取INI文件时,我们可以先使用QSettings的构造函数来指定INI文件的路径,然后使用value()函数来获取指定节下的键值对。
为了读取某个节下的所有键值对,我们可以使用childGroups()函数来获取所有的子节名,然后再遍历每个子节获取其对应的键值对。
下面是一个简单的示例代码,展示了如何使用Qt框架中的QSettings 类来读取INI文件中某个节下的所有键值对:cppinclude <QSettings>include <QDebug>void readIniFile(const QString& filePath){QSettings settings(filePath, QSettings::IniFormat);QStringList sectionList = settings.childGroups();foreach (const QString& section, sectionList) {settings.beginGroup(section);QStringList keys = settings.childKeys();foreach (const QString& key, keys) {QString value = settings.value(key).toString();qDebug() << "Section:" << section << "Key:" << key << "Value:" << value;}settings.endGroup();}}int main(){QString filePath = "config.ini";readIniFile(filePath);return 0;}以上代码中,readIniFile()函数用于读取INI文件中某个节下的所有键值对。
ini配置文件操作方法一、ini文件介绍ini配置文件常用于存储项目全局变量如:接口地址、输出文件路径、项目地址、用户名、密码等二、ini文件编写格式[节点]选项=选项值;表示注释注意:节点名不可以重复【所以写入新节点前要判断是否存在】三、.ini 文件读取1、.ini文件读import configparserconfig = configparser.ConfigParser()config.read('config.ini')# 获取所有节点sec = config.sections()print(sec)# 获取单个节点下所有选项db = config.options(section="database")print(db)# 获取单个节点下某个选项值username = config.get(section="database", option="username")print(username)# 获取某个节点下所有选项及选项值value = config.items(section="database")print(f"获取到的值是:{value}")2、ini文件写# 增加一个节点config.add_section("db")# 给节点增加选项和值config.set(section="db", option="usr", value="chuanzhang") # 保存操作with open(os.path.dirname(__file__)+'/config.ini', mode='w+') as file:config.write(file)file.close()3、删除# 删除节点下某个选项config.remove_option(section="db", option="pwd")with open(os.path.dirname(__file__)+'/config.ini', mode='w+') as opt:config.write(opt)opt.close()# 删除节点config.remove_section("db")# 删除后保存with open(os.path.dirname(__file__)+'/config.ini', mode='w+') as data:config.write(data)data.close()。
一、config.ini 配置文件[DATABASE]host = 192.1.1.1username = rootpassword = rootport = 3306database = jforum[URL]#ip,端口ip =127.0.0.1port= 8089二、操作ini常用方法‐‐read():读取配置文件‐‐sections():读取配置文件中所有的section(如上配置文件:DATABASE,URL)‐‐options(section):读取该section下所有的option(可以理解成读取该组下的所有key,如options("URL"),值['ip', 'port'])‐‐items(section):读取该section下的所有key‐vaule,并以键值对形式输出(如:sectioitems("URL"),值:[('ip', '127.0.0.1'), ('port', '8089')])‐‐get(section, option):读取指定section下面的option的值(可以理解成,读取具体某个section下面指定key的值,如config.get('URL','ip')),值:127.0.0.1)‐‐add_secti on(section):添加一个section,参数为section的名称‐‐set(section, option, value):在section下面添加一条数据(key=value)‐‐add与set需调用write(open(configPath, "a"))才可以写入ini文件 #参数a表示最近,w重写‐‐remove_secit on(seciton) 删除整个seciton‐‐config.remove_opti on(seciton,key) ,删除seciton的某个key值三、源码举例#!/usr/bin/python3# encoding:utf‐8'''Created on 2020‐04‐19 23:19@author: Administrator'''import configparserimport osfrom turtle import readconfig#获取文件绝对路径 D:\common\proDir = os.getcwd()#拼接文件路径 D:\common\config.iniconfigPath = os.path.join(proDir, "config.ini")#创建管理对象config = configparser.ConfigParser()#读取配置类class readConfig():#读取ini文件config.read(configPath, encoding="UTF‐8")#获取所有的section@staticmethoddef get_sections():return config.sections()@staticmethoddef get_items(section):return config.items(section)@staticmethoddef get_options(section):return config.options(section)@staticmethoddef get_Vaule(section,name):value = config.get(section, name)return value@staticmethoddef add_section():config.add_section('HTTP')@staticmethoddef set_section(section, option, value):config.set(section, option, value)@staticmethoddef remove_seciton(seciton):config.remove_section(seciton)@staticmethoddef remove_seciton_value(seciton,key):config.remove_option(seciton,key)if __name__=='__main__':print('‐‐‐‐‐1.打印所有section')print(readConfig.get_sections())print('‐‐‐‐‐2.打印section=URL的所有key‐Value值')print(readConfig.get_items("URL"))print('‐‐‐‐‐3.打印section=URL的所有key值')print(readConfig.get_options("URL"))print('‐‐‐‐‐4.打印section=URL,key=ip的value值')print(readConfig.get_Vaule('URL','ip'))print('‐‐‐‐‐5.新增之后打印所有section,注意有一个新增值HTTP')readConfig.add_section()print(readConfig.get_sections())print('‐‐‐‐‐6.新增section=HTTP,key=port,value=443,查看值,443为新增的值')readConfig.set_section('HTTP', 'port', '443')print(readConfig.get_Vaule('HTTP','port'))#上面的新增并不会真的真正写入,需加这个才能正在写入ini文件,如果参数为"w"则表示删除文件重新写入,"a"为追加模式写入#config.write(open(configPath, "a"))print('‐‐‐‐‐7.删除sections=URL,打印所有sections,注意URL已被删除')readConfig.remove_seciton("URL")print(readConfig.get_sections())print('‐‐‐‐‐8.删除sections=DATABASE,key=host,打印所有key值,注意host已被删除')readConfig.remove_seciton_value('DATABASE','host')print(readConfig.get_options('DATABASE'))运行结果‐‐‐‐‐1.打印所有section['DATABASE', 'URL']‐‐‐‐‐2.打印section=URL的所有key‐Value值[('ip', '127.0.0.1'), ('port', '8089')]‐‐‐‐‐3.打印section=URL的所有key值['ip', 'port']‐‐‐‐‐4.打印section=URL,key=ip的value值127.0.0.1‐‐‐‐‐5.新增之后打印所有section,注意有一个新增值HTTP['DATABASE', 'URL', 'HTTP']‐‐‐‐‐6.新增section=HTTP,key=port,value=443,查看值,443为新增的值 443‐‐‐‐‐7.删除sections=URL,打印所有sections,注意URL已被删除['DATABASE', 'HTTP']‐‐‐‐‐8.删除sections=DATABASE,key=host,打印所有key值,注意host已被删除 ['username', 'password', 'port', 'database']。
ini文件(即Initialization file),这种类型的文件中通常存放的是一个程序的初始化信息。
ini文件由若干个节(Section)组成,每个Section由若干键(Key)组成,每个Key可以赋相应的值。
读写ini文件实际上就是读写某个的Section中相应的Key的值,而这只要借助几个函数即可完成一、向ini文件中写入信息的函数1. 把信息写入系统的win.ini文件BOOL WriteProfileString(LPCTSTR lpAppName, // 节的名字,是一个以0结束的字符串LPCTSTR lpKeyName, // 键的名字,是一个以0结束的字符串。
若为NULL,则删除整个节LPCTSTR lpString // 键的值,是一个以0结束的字符串。
若为NULL,则删除对应的键)2. 把信息写入自己定义的.ini文件BOOL WritePrivateProfileString(LPCTSTR lpAppName, //节的名字,是一个以0结束的字符串LPCTSTR lpKeyName, // 键的名字,是一个以0结束的字符串。
若为NULL,则删除整个 LPCTSTR lpString, //键的名字,是一个以0结束的字符串。
若为NULL,则删除整个节LPCTSTR lpFileName // 要写入的文件的文件名。
若该ini文件与程序在同一个目录下,也可使用相对路径,否则需要给出绝对路径。
)如:::WriteProfileString("Test","id","xym");//在win.ini中创建一个Test节,并在该节中创建一个键id,其值为xym::WritePrivateProfileString("Test","id","xym","d:\vc\Ex1\ex1.ini");//在Ex1目录下的ex1.ini中创建一个Test节,并在该节中创建一个键id,其值为xym//若Ex1.ini文件与读写该文件的程序在同一个目录下,则上面语句也可写为:::WritePrivateProfileString("Test","id","xym",".\ex1.ini");需要注意的是,C系列的语言中,转义字符'\'表示反斜线''。
ini文件格式INI文件由节、键、值组成。
节[section]参数(键=值)name=value下面是一个ini文件的例子[Section1Name]KeyName1=value1KeyName2=value2...[Section2Name]KeyName21=value21KeyName22=value22其中:[Section1Name]用来表示一个段落。
因为INI文件可能是项目中共用的,所以使用[Section Name]段名来区分不同用途的参数区。
例如:[Section1Name]表示传感器灵敏度参数区;[Section2Name]表示测量通道参数区等等。
注解:使用分号表示(;)。
在分号后面的文字,直到该行结尾都全部为注解。
二Qt写ini文件[cpp]view plaincopyprint?1#include<QtCore/QCoreApplication>2#include<QSettings>3int main(int argc,char*argv[])4{5QCoreApplication a(argc,argv);6//Qt中使用QSettings类读写ini文件7//QSettings构造函数的第一个参数是ini文件的路径,第二个参数表示针对ini文件,第三个参数可以缺省8QSettings*configIniWrite=new QSettings("hahaya.ini",QSettings::IniFormat);9//向ini文件中写入内容,setValue函数的两个参数是键值对10//向ini文件的第一个节写入内容,ip节下的第一个参数11configIniWrite->setValue("/ip/first","192.168.0.1");12//向ini文件的第一个节写入内容,ip节下的第二个参数13configIniWrite->setValue("ip/second","127.0.0.1");14//向ini文件的第二个节写入内容,port节下的第一个参数15configIniWrite->setValue("port/open","2222");16//写入完成后删除指针17delete configIniWrite;1819return a.exec();20}[cpp]view plain copyprint?21#include<QtCore/QCoreApplication>22#include<QSettings>23int main(int argc,char*argv[])24{25QCoreApplication a(argc,argv);26//Qt中使用QSettings类读写ini文件27//QSettings构造函数的第一个参数是ini文件的路径,第二个参数表示针对ini文件,第三个参数可以缺省28QSettings*configIniWrite=new QSettings("hahaya.ini",QSettings::IniFormat);29//向ini文件中写入内容,setValue函数的两个参数是键值对30//向ini文件的第一个节写入内容,ip节下的第一个参数31configIniWrite->setValue("/ip/first","192.168.0.1");32//向ini文件的第一个节写入内容,ip节下的第二个参数33configIniWrite->setValue("ip/second","127.0.0.1");34//向ini文件的第二个节写入内容,port节下的第一个参数35configIniWrite->setValue("port/open","2222");36//写入完成后删除指针37delete configIniWrite;3839return a.exec();40}运行程序后,打开程序目录下的hahaya.ini文件,结果如下图所示:三Qt读ini文件[cpp]view plaincopyprint?41#include<QtCore/QCoreApplication>42#include<QSettings>43#include<QString>44#include<QDebug>45int main(int argc,char*argv[])46{47QCoreApplication a(argc,argv);4849QSettings*configIniRead=new QSettings("hahaya.ini",QSettings::IniFormat);50//将读取到的ini文件保存在QString中,先取值,然后通过toString()函数转换成QString类型51QString ipResult=configIniRead->value("/ip/second").toString();52QString portResult=configIniRead->value("/port/open").toString();53//打印得到的结果54qDebug()<<ipResult;55qDebug()<<portResult;56//读入入完成后删除指针57delete configIniRead;58return a.exec();59}[cpp]view plain copyprint?60#include<QtCore/QCoreApplication>61#include<QSettings>62#include<QString>63#include<QDebug>64int main(int argc,char*argv[])65{66QCoreApplication a(argc,argv);6768QSettings*configIniRead=new QSettings("hahaya.ini",QSettings::IniFormat);69//将读取到的ini文件保存在QString中,先取值,然后通过toString()函数转换成QString类型70QString ipResult=configIniRead->value("/ip/second").toString();71QString portResult=configIniRead->value("/port/open").toString();72//打印得到的结果73qDebug()<<ipResult;74qDebug()<<portResult;75//读入入完成后删除指针76delete configIniRead;77return a.exec();78}程序运行截图:。
C# 操作INI文件类private void testini_load(object sender, system.eventargs e){//创建一个inifile对象,参数为文件路径,如果不存在他会自动创建的inifile inf=new inifile(@"d:\工作目录\vspp\vsppserver\bin\debug\compiled.ini"); //显示ini设置的结构foreach(string k in inf.segments.keys){treenode o=new treenode(k);inisegment s=inf.segments[k]; //取出当前设置节foreach(string k1 in s.items.keys){treenode o1=new treenode(k1+" = "+s.items[k1].value); //访问设置节中每个设置项o.nodes.add(o1);}treeview1.nodes.add(o);}//添加一个设置inf.segments.add("test"); //添加test节inf.segments["test"].items.add("ip","192.168.0.1"); //添加一个设置项//快速添加一个设置项inf.segments["测试"].items["host"].value="localhost"; // :)和上面两行相同的效果//读取也是同样的方便messagebox.show(inf.segments["测试"].items["host"].value);//如果不存在这样的设置项,将返回空字符串并创建这个项messagebox.show(inf.segments["测试"].items["server"].value);//清除一个设置节下面的所有设置项//inf.segments["action"].clear();}再show代码:using system;using system.io;using system.data;using system.text;using system.collections;using system.text.regularexpressions;using system.runtime.interopservices; namespace eglic{#region ini文件操作类/// <summary>/// 设置节/// </summary>public class inisegment{private string __name;private inisegments __owner;/// <summary>/// 所有设置项集合/// </summary>public iniitems items;/// <summary>/// 构造函数/// </summary>/// <param name="o">owner</param>/// <param name="vname">设置节名称</param> public inisegment(inisegments o,string vname) {__owner=o;__name=vname;items=new iniitems(this);o.owner.getsegment(this);}/// <summary>/// 获取设置节的名称/// </summary>public string name{get {return __name;}}/// <summary>/// 获取segment的owner:inisegments集合/// </summary>public inisegments owner{get {return __owner;}}/// <summary>/// 清除所有设置项/// </summary>public void clear(){__owner.owner.writesegment(__name,"\0\0"); }}/// <summary>/// 设置节集合/// </summary>public class inisegments : dictionarybase{private inifile __owner;/// <summary>/// 构造函数/// </summary>/// <param name="o">owner</param>public inisegments(inifile o){__owner=o;}/// <summary>/// 获取此对象的owner:inifile类/// </summary>public inifile owner{get {return __owner;}}/// <summary>/// 添加一个已存在的设置节/// </summary>/// <param name="o">设置节对象</param>public void add(inisegment o){if(!dictionary.contains())dictionary.add(,o);}/// <summary>/// 添加一个可能不存在的设置节(创建一个设置节) /// </summary>/// <param name="vname">设置节名称</param>/// <returns>添加的设置节</returns>public inisegment add(string vname){if(dictionary.contains(vname))return (inisegment)dictionary[vname];inisegment o=new inisegment(this,vname);dictionary.add(vname,o);return o;}/// <summary>/// 获取索引集合/// </summary>public icollection keys{get {return dictionary.keys;}}/// <summary>/// 获取值集合/// </summary>public icollection values{get {return dictionary.values;}}/// <summary>/// 获取设置节/// </summary>public inisegment this [string vname]{get{if(!dictionary.contains(vname))return this.add(vname);elsereturn (inisegment)dictionary[vname];}}/// <summary>/// 获取是否包含某设置节/// </summary>/// <param name="vname">设置节名称</param> /// <returns>是否</returns>public bool contains(string vname){return dictionary.contains(vname);}}/// <summary>/// 设置项/// </summary>public class iniitem{private string __name;private string __value;private iniitems __owner;/// <summary>/// 构造函数/// </summary>/// <param name="o">owner</param>/// <param name="vname">名称</param>/// <param name="vvalue">值</param>public iniitem(iniitems o,string vname,string vvalue) {__owner=o;__name=vname;__value=vvalue;if(!o.contains(vname))o.owner.owner.owner.setstring(,vname,vvalue);}/// <summary>/// 获取名称/// </summary>public string name{get {return __name;}}/// <summary>/// 获取设置值/// </summary>public string value{get {return __value;}set {__value=value;__owner.owner.owner.owner.setstring(__,__name,value); }}/// <summary>/// 获取owner/// </summary>public iniitems owner{get {return __owner;}}}/// <summary>/// 设置项集合/// </summary>public class iniitems : dictionarybase{private inisegment __owner;/// <summary>/// 构造函数/// </summary>/// <param name="o">owner</param>public iniitems(inisegment o){__owner=o;}/// <summary>/// 获取owner/// </summary>public inisegment owner{get {return __owner;}}/// <summary>/// 添加一个已存在的设置项/// </summary>/// <param name="o">设置项</param>public void add(iniitem o){if(!dictionary.contains())dictionary.add(,o);}/// <summary>/// 获取是否包含指定名称的设置项/// </summary>/// <param name="vname">设置项名称</param> /// <returns>是否</returns>public bool contains(string vname){return dictionary.contains(vname);}/// <summary>/// 获取所有的索引集合/// </summary>public icollection keys{get {return dictionary.keys;}/// <summary>/// 获取所有的值集合/// </summary>public icollection values{get {return dictionary.values;}}/// <summary>/// 添加一个可能不存在的设置项(创建一个设置项) /// </summary>/// <param name="vname">设置项名</param>/// <param name="vvalue">设置项值</param>/// <returns>创建的设置项iniitem对象</returns>public iniitem add(string vname,string vvalue){if(dictionary.contains(vname))return (iniitem)dictionary[vname];else{iniitem o=new iniitem(this,vname,vvalue);this.add(o);return o;}}/// <summary>/// 获取指定索引的设置项/// </summary>public iniitem this[string vname]{get {if(dictionary.contains(vname))return (iniitem)dictionary[vname];elsereturn this.add(vname,"");}}/// <summary>/// ini文件操作类/// </summary>public class inifile{#region 导入dll函数[dllimport("kernel32.dll")] public extern static int getprivateprofileinta(string segname,string keyname,int idefault,string filename);[dllimport("kernel32.dll")] public extern static int getprivateprofilestringa(string segname,string keyname,string sdefault,stringbuilder retvalue,int nsize,string filename);[dllimport("kernel32.dll")] public extern static int getprivateprofilesectiona(string segname,byte [] sdata,int nsize,string filename);[dllimport("kernel32.dll")] public extern static int writeprivateprofilesectiona(string segname,byte [] sdata,string filename);[dllimport("kernel32.dll")] public extern static int writeprivateprofilestringa(string segname,string keyname,string svalue,string filename);[dllimport("kernel32.dll")] public extern static int getprivateprofilesectionnamesa(byte [] vdata,intilen,string filename);#endregionprivate string __path;/// <summary>/// 所有的设置节/// </summary>public inisegments segments;/// <summary>/// 构造函数/// </summary>/// <param name="vpath">ini文件路径</param>public inifile(string vpath){__path=vpath;segments=new inisegments(this);byte [] bufsegs=new byte [32767];int rel=getprivateprofilesectionnamesa(bufsegs,32767,__path);int icnt,ipos;string tmp;if(rel>0){icnt=0;ipos=0;for(icnt=0;icnt<rel;icnt++){if(bufsegs[icnt]==0x00){tmp=system.text.asciiencoding.default.getstring(bufsegs,ipos,icnt).trim(); ipos=icnt+1;if(tmp!="")segments.add(tmp);}}}}/// <summary>/// 获取ini文件路径/// </summary>public string path{get {return __path;}}/// <summary>/// 读取一个整数型的设置值/// </summary>/// <param name="segname">设置节名</param>/// <param name="keyname">设置项名</param>/// <param name="idefault">默认值</param>/// <returns>设置值</returns>public int getint(string segname,string keyname,int idefault){return getprivateprofileinta(segname,keyname,idefault,__path);}/// <summary>/// 读取一个字符串型设置值/// </summary>/// <param name="segname">设置节名</param>/// <param name="keyname">设置项名</param>/// <param name="sdefault">默认值</param>/// <returns>设置值</returns>public string getstring(string segname,string keyname,string sdefault){stringbuilder red=new stringbuilder(1024);getprivateprofilestringa(segname,keyname,"",red,1024,__path);return red.tostring();}/// <summary>/// 写入设置项/// </summary>/// <param name="segname">设置节名</param>/// <param name="keyname">设置项名</param>/// <param name="vvalue">设置值</param>public void setstring(string segname,string keyname,string vvalue){writeprivateprofilestringa(segname,keyname,vvalue,__path);}/// <summary>/// 写入一个设置节/// </summary>/// <param name="segname">设置节名</param>/// <param name="vdata">数据</param>/// <remarks>/// 数据为多个设置项组成的字符串,每个设置项之间用"\0" 分割/// 字符串最后用"\0\0" 结束/// </remarks>/// <example>/// writesegment(segname,"\0\0"); 能用于清除一个设置节下的所有设置项/// </example>public void writesegment(string segname,string vdata){writeprivateprofilesectiona(segname,system.text.asciiencoding.default.getbytes(vdata),__path); }/// <summary>/// 读取一个设置节下面的所有设置项/// </summary>/// <param name="o">要读取的设置节</param>public void getsegment(inisegment o){byte [] vdata=new byte [32767];int rlen=getprivateprofilesectiona(,vdata,32767,__path);o.items.clear();if(rlen<1) return;string tmp="";int ipos,icnt;ipos=0;for(icnt=0;icnt<rlen;icnt++){if(vdata[icnt]==0x00){tmp=system.text.asciiencoding.default.getstring(vdata,ipos,icnt-ipos).trim(); if(tmp!=""){string [] t=tmp.split(=);if(t.length<=1)o.items.add(t[0],"");elseo.items.add(t[0],t[1]);}ipos=icnt+1;}}}}#endregion}。
一卡通机器操作INI文件设计版本说明对应应用程序: E3iCard3.exe应用程序ini 文件名: E3ICard3.ini机器操作INI文件设计处理一)前述:一般而言,在智能卡系统(非接触式IC卡)中,很多时侯操作都是离线式的设备较多,因此,对于离线式设备来说,由于与计算机没有直接相联,因此,数据存储很自然就不会直接存储在计算机内,而是存储在智能卡机器本身。
从而,要求我们针对摆放在不同地点中的机器数据进行相应的采集。
因此,采集方法有人工采集,自动定时采集两种方法。
而从数据采集中来看,我们认为定时自动采集更符合实际生产所需。
二)机器操作定义:对于机器操作一般来说分为两部分,(1). 一部分是针对机器取数用或上传参数用。
(2). 另一部分是将取到的数据读入到数据库,以便后续的应用程序处理。
由于考虑到系统扩展性,或者要兼容未来的扩展的机器设备,因此,特别编写一个较为统一的机器操作系统,进行数据统一处理。
也就是说,针对不同的机器定义特定的机器接口,然后统一调用机器的取数方法。
三)INI文件中[Section]部分定义3.1) 对于机器设备[Section]操作,一般来说包含以下几个参数内容:(1). 机器起始号,机器结束号(2). 串口号3.2) 对于数据库操作相对参数较少,一般就是导入到哪个数据库,对应哪个表,对应字段,文本格式分隔符或者自哪位至哪位。
同时,为着区分两种不同的操作方式,我们在ini 文件中的[SectionName] 进行区分。
对于直接操作机器,以[Mach_?] 区分对于操作数据库,以[DB_?]区分,两种不同[Section] 的KeyName 必须包含OperType:integer ; //操作类型---对机器操作还是对数据库操作。
OPerTimestr:string ; //该操作安排执行时间HourInterVal:integer ; //该操作每次操作后再次操作时的小时操作间隔对于[Mach_?] ,还会包含以下几个KeynameMach_Begin:integer ; //机器起始号Mach_End:integer ; //机器结束号Machtype:integer ; //对应的机器类型,消费机,考勤机DataSaveDir:string ; //数据保存路径对于{DB_?} ,则还包含以下几个DBconnstr:string ; //数据库连接串DataPathDir:string ; //文件保存的路径。
INI文件其实是一种具有特定结构的文本文件,它的构成分为三部分,结构如下:[Section1]key 1 = value2key 1 = value2……[Section2]key 1 = value1key 2 = value2……文件由若干个段落(section)组成,每个段落又分成若干个键(key)和值(value)。
Windows 系统自带的Win32的API函数GetPrivateProfileString()和WritePrivateProfileString()分别实现了对INI文件的读写操作,他们位于kernel32.dll下。
但是令人遗憾的是C#所使用的.NET框架下的公共类库并没有提供直接操作INI文件的类,所以唯一比较理想的方法就是调用API函数。
然后,.Net框架下的类库是基于托管代码的,而API函数是基于非托管代码的,(在运行库的控制下执行的代码称作托管代码。
相反,在运行库之外运行的代码称作非托管代码。
)如何实现托管代码与非托管代码之间的操作呢?.Net框架的System.Runtime.InteropServices命名空间下提供各种各样支持COM interop及平台调用服务的成员,其中最重要的属性之一DllImportAttribute 可以用来定义用于访问非托管API的平台调用方法,它提供了对从非托管DLL导出的函数进行调用所必需的信息。
下面就来看一下如何实现C#与API函数的互操作。
读操作:[DllImport("kernel32")]private static extern int GetPrivateProfileString(string section, string key, string d efVal, StringBuilder retVal, int size, string filePath);section:要读取的段落名key: 要读取的键defVal: 读取异常的情况下的缺省值retVal: key所对应的值,如果该key不存在则返回空值size: 值允许的大小filePath: INI文件的完整路径和文件名写操作:[DllImport("kernel32")]private static extern long WritePrivateProfileString(string section, string key, strin g val, string filePath);section: 要写入的段落名key: 要写入的键,如果该key存在则覆盖写入val: key所对应的值filePath: INI文件的完整路径和文件名这样,在就可以使用对他们的调用,用常规的方式定义一个名为IniFile类:1using System;2using System.Runtime.InteropServices;3using System.Text;45namespace IPVOD.Hotel.Remoting6{7///<summary>8///INI文件的操作类9///</summary>10public class IniFile11{12public string Path;1314public IniFile(string path)15{16this.Path = path;17}1819声明读写INI文件的API函数#region声明读写INI文件的API函数20[DllImport("kernel32")]21private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);2223[DllImport("kernel32")]24private static extern int GetPrivateProfileString(string section, string ke y, string defVal, StringBuilder retVal, int size, string filePath);2526[DllImport("kernel32")]27private static extern int GetPrivateProfileString(string section, string ke y, string defVal, Byte[] retVal, int size, string filePath);28#endregion2930///<summary>31///写INI文件32///</summary>33///<param name="section">段落</param>34///<param name="key">键</param>35///<param name="iValue">值</param>36public void IniWriteValue(string section, string key, string iValue)37{38WritePrivateProfileString(section, key, iValue, this.Path);39}4041///<summary>42///读取INI文件43///</summary>44///<param name="section">段落</param>45///<param name="key">键</param>46///<returns>返回的键值</returns>47public string IniReadValue(string section, string key)48{49StringBuilder temp = new StringBuilder(255);5051int i = GetPrivateProfileString(section, key, "", temp, 255, this.Pat h);52return temp.ToString();53}5455///<summary>56///读取INI文件57///</summary>58///<param name="Section">段,格式[]</param>59///<param name="Key">键</param>60///<returns>返回byte类型的section组或键值组</returns>61public byte[] IniReadValues(string section, string key)62{63byte[] temp = new byte[255];6465int i = GetPrivateProfileString(section, key, "", temp, 255, this.Pat h);66return temp;67}68}69}70注意:我增加了DLL导出的函数GetPrivateProfileString的重载,说明如下:[DllImport("kernel32")]private static extern int GetPrivateProfileString(string section, string key, string d efVal, Byte[] retVal, int size, string filePath);section:要读取的段落名key: 要读取的键defVal: 读取异常的情况下的缺省值retVal: 此参数类型不是string,而是Byte[]用于返回byte类型的section组或键值组。
Qt读写三种⽂件,QSettings读ini配置⽂件,QJsonDocument读JSON。
第⼀种INI配置⽂件.ini ⽂件是Initialization File的缩写,即初始化⽂件。
除了windows现在很多其他操作系统下⾯的应⽤软件也有.ini⽂件,⽤来配置应⽤软件以实现不同⽤户的要求。
⼀般不⽤直接编辑这些.ini⽂件,应⽤程序的图形界⾯即可操作以实现相同的功能。
它可以⽤来存放软件信息,注册表信息等。
读INI⽂件INI⽂件内容如下:[conn]ip=127.0.0.1port=8080databaseversion=QSQLITEdatabasename=studentusername=YYCpassword=rootqreadini.h⽂件内容如下:#ifndef QREADINI_H#define QREADINI_H#include<QSettings>#define DATACONFIG QReadIni::getInstance()->getIniConfig()typedef struct IniConfig{QString ip; //IP地址QString port; //端⼝QString dataBaseVersion; //数据库版本QString dataBaseName; //数据库名称QString userName; //⽤户名QString passWord; //密码}IniConfig;class QReadIni{public:static QReadIni*getInstance();void readIni();const IniConfig &getIniConfig();private:QReadIni();IniConfig iniConfig;static QReadIni*instance;};#endif// QREADINI_Hqreadini.cpp⽂件内容如下:#include "qreadini.h"QReadIni*QReadIni::instance = NULL;QReadIni *QReadIni::getInstance(){if(instance == NULL){instance = new QReadIni();}return instance;}QReadIni::QReadIni(){this->readIni();}void QReadIni::readIni(){QSettings * configIniRead = new QSettings("config.ini",QSettings::IniFormat);//初始化读取Ini⽂件对象 iniConfig.ip = configIniRead->value("conn/ip").toString(); //IP地址iniConfig.port = configIniRead->value("conn/port").toString(); //端⼝iniConfig.dataBaseVersion = configIniRead->value("conn/databaseversion").toString();//数据库版本iniConfig.dataBaseName = configIniRead->value("conn/databasename").toString(); //数据库名称 erName = configIniRead->value("conn/username").toString(); //⽤户名iniConfig.passWord = configIniRead->value("conn/password").toString(); //密码delete configIniRead;}const IniConfig &QReadIni::getIniConfig(){return iniConfig;}写ini⽂件#include <QtCore/QCoreApplication>#include <QSettings>int main(int argc, char *argv[]){QCoreApplication a(argc, argv);//Qt中使⽤QSettings类读写ini⽂件//QSettings构造函数的第⼀个参数是ini⽂件的路径,第⼆个参数表⽰针对ini⽂件,第三个参数可以缺省QSettings *configIniWrite = new QSettings("hahaya.ini", QSettings::IniFormat);//向ini⽂件中写⼊内容,setValue函数的两个参数是键值对//向ini⽂件的第⼀个节写⼊内容,ip节下的第⼀个参数configIniWrite->setValue("/ip/first", "192.168.0.1");//向ini⽂件的第⼀个节写⼊内容,ip节下的第⼆个参数configIniWrite->setValue("ip/second", "127.0.0.1");//向ini⽂件的第⼆个节写⼊内容,port节下的第⼀个参数configIniWrite->setValue("port/open", "2222");//写⼊完成后删除指针delete configIniWrite;return a.exec();}第⼆种JSON⽂件"conn": {"ip": "127.0.0.1","port": "8080","databaseversion": "QSQLITE","databasename": "student","username": "YYC","password": "root"}}qreadjson.h⽂件内容如下#ifndef QREADJSON_H#define QREADJSON_H#include <QString>#include <QFile>#include <QIODevice>#include <QDomNodeList>#include <QJsonDocument>#include <QJsonObject>#define JSONCONFIG QReadJson::getInstance()->getJsonConfig() typedef struct JsonConfig{QString ip; //IP地址QString port; //端⼝QString dataBaseVersion; //数据库版本QString dataBaseName; //数据库名称QString userName; //⽤户名QString passWord; //密码}JsonConfig;class QReadJson{public:static QReadJson * getInstance();bool readJson();const JsonConfig &getJsonConfig();private:QReadJson();static QReadJson * instance;JsonConfig jsonConfig;};#endif// QREADJSON_Hqreadjson.cpp内容如下:#include"qreadjson.h"QReadJson * QReadJson::instance = NULL;QReadJson *QReadJson::getInstance(){if(NULL == instance){instance = new QReadJson();return instance;}QReadJson::QReadJson(){this->readJson();}bool QReadJson::readJson(){QString strJson;QFile *file=new QFile("config.json");if(file->open(QIODevice::ReadOnly | QIODevice::Text)){strJson = file->readAll();file->close();}else{return false;}file->close();QJsonDocument jsonDom = QJsonDocument::fromJson(strJson.toUtf8()); QJsonObject jsonObject = jsonDom.object();QJsonValue jsonValue = jsonObject.value(QString("conn"));QJsonObject objectItem = jsonValue.toObject();jsonConfig.ip = objectItem["ip"].toString();jsonConfig.port = objectItem["port"].toString();jsonConfig.dataBaseVersion = objectItem["databaseversion"].toString(); jsonConfig.dataBaseName = objectItem["databasename"].toString();erName = objectItem["username"].toString();jsonConfig.passWord = objectItem["password"].toString();delete file;return true;}const JsonConfig &QReadJson::getJsonConfig(){return jsonConfig;}第三种是读取xml⽂件:<?xml version="1.0" encoding="UTF-8"?>-<data>-<database><ip>127.0.0.1</ip><port>8080</port><databaseversion>QSQLITE</databaseversion><databasename>student.db</databasename><username>root</username><password>123</password></database>qreadxml.h⽂件内容如下:#ifndef QREADXML_H#define QREADXML_H#include<QString>#include<QtXml>#include<QFile>#include<QIODevice>#include<QDomNodeList>#define XMLCONFIG QReadXml::getInstance()->getXmlConfig() typedef struct XmlConfig{QString ip; //IP地址QString port; //端⼝QString dataBaseVersion; //数据库版本QString dataBaseName; //数据库名称QString userName; //⽤户名QString passWord; //密码}XmlConfig;class QReadXml{public:static QReadXml * getInstance();bool readXML();const XmlConfig &getXmlConfig();private:QReadXml();XmlConfig xmlConfig;static QReadXml * instance;};#endif// QREADXML_Hqreadxml.cpp⽂件如下#include "qreadxml.h"QReadXml *QReadXml::instance = NULL;QReadXml *QReadXml::getInstance(){if(NULL == instance){instance = new QReadXml();}return instance;}QReadXml::QReadXml(){this->readXML();}bool QReadXml::readXML(){int countData = 0;QDomDocument dom;QFile *file=new QFile("config.xml");if(file->open(QIODevice::ReadOnly)){if(!dom.setContent(file)) //将该xml⽂件导⼊到dom中{file->close();return false;}}else{return false;}file->close();QDomElement docElem = dom.documentElement(); //返回根元素QDomNode node = docElem.firstChild(); //返回根节点的第⼀个⼦节点while(!node.isNull()) //如果节点不为空{if(node.isElement()) //如果节点是元素{QDomElement element=node.toElement();//将其转化为元素QDomNodeList list=element.childNodes();//取出该元素的所有⼦节点放到list中 //将⼦节点元素全部取出来for(int i = 0; i < list.count(); i ++){QDomNode domNode = list.at(i);if(domNode.isElement()){//取出我们所要的数据switch(i){case0:xmlConfig.ip = domNode.toElement().text();break;case1:xmlConfig.port = domNode.toElement().text();break;case2:xmlConfig.dataBaseVersion = domNode.toElement().text();break;case3:xmlConfig.dataBaseName = domNode.toElement().text();break;case4:erName = domNode.toElement().text();break;case5:xmlConfig.passWord = domNode.toElement().text();break;}}}}countData++;node = node.nextSibling(); //下⼀个兄弟节点}return countData > 0 ? true : false;}const XmlConfig &QReadXml::getXmlConfig(){return xmlConfig;}原⽂:。
ini格式⽂件操作⽅法ini格式⽂件ini⽂件是Initialization File的缩写,平时⽤于存储软件的的配置⽂件。
例如:MySQL数据库的配置⽂件。
[mysqld]datadir=/var/lib/mysqlsocket=/var/lib/mysql/mysql.socklog-bin=py-mysql-bincharacter-set-server=utf8collation-server=utf8_general_cilog-error=/var/log/mysqld.log# Disabling symbolic-links is recommended to prevent assorted security riskssymbolic-links=0[mysqld_safe]log-error=/var/log/mariadb/mariadb.logpid-file=/var/run/mariadb/mariadb.pid[client]default-character-set=utf8这种格式是可以直接使⽤open来出来,考虑到⾃⼰处理⽐较⿇烦,所以Python为我们提供了更为⽅便的⽅式。
import configparserconfig = configparser.ConfigParser()config.read('files/my.ini', encoding='utf-8')# config.read('/Users/wupeiqi/PycharmProjects/luffyCourse/day09/files/my.ini', encoding='utf-8')# 1.获取所有的节点"""result = config.sections()print(result) # ['mysqld', 'mysqld_safe', 'client']"""# 2.获取节点下的键值"""result = config.items("mysqld_safe")print(result) # [('log-error', '/var/log/mariadb/mariadb.log'), ('pid-file', '/var/run/mariadb/mariadb.pid')]for key, value in config.items("mysqld_safe"):print(key, value)"""# 3.获取某个节点下的键对应的值"""result = config.get("mysqld","collation-server")print(result)"""# 4.其他# 4.1 是否存在节点# v1 = config.has_section("client")# print(v1)# 4.2 添加⼀个节点# config.add_section("group")# config.set('group','name','wupeiqi')# config.set('client','name','wupeiqi')# config.write(open('files/new.ini', mode='w', encoding='utf-8'))# 4.3 删除# config.remove_section('client')# config.remove_option("mysqld", "datadir")# config.write(open('files/new.ini', mode='w', encoding='utf-8'))读取所有节点import configparserconfig = configparser.ConfigParser()config.read('/Users/wupeiqi/PycharmProjects/luffyCourse/day09/files/my.conf', encoding='utf-8')# config.read('my.conf', encoding='utf-8')ret = config.sections()print(ret)>>输出['mysqld', 'mysqld_safe', 'client']读取节点下的键值import configparserconfig = configparser.ConfigParser()config.read('/Users/wupeiqi/PycharmProjects/luffyCourse/day09/files/my.conf', encoding='utf-8') # config.read('my.conf', encoding='utf-8')item_list = config.items("mysqld_safe")print(item_list)>>输出[('log-error', '/var/log/mariadb/mariadb.log'), ('pid-file', '/var/run/mariadb/mariadb.pid')]读取节点下值(根据节点+键)import configparserconfig = configparser.ConfigParser()config.read('/Users/wupeiqi/PycharmProjects/luffyCourse/day09/files/my.conf', encoding='utf-8') value = config.get('mysqld', 'log-bin')print(value)>>输出py-mysql-bin检查、删除、添加节点import configparserconfig = configparser.ConfigParser()config.read('/Users/wupeiqi/PycharmProjects/luffyCourse/day09/files/my.conf', encoding='utf-8') # config.read('my.conf', encoding='utf-8')# 检查has_sec = config.has_section('mysqld')print(has_sec)# 添加节点config.add_section("SEC_1")# 节点中设置键值config.set('SEC_1', 'k10', "123")config.set('SEC_1', 'name', "哈哈哈哈哈")config.add_section("SEC_2")config.set('SEC_2', 'k10', "123")# 内容写⼊新⽂件config.write(open('/Users/wupeiqi/PycharmProjects/luffyCourse/day09/files/xxoo.conf', 'w'))# 删除节点config.remove_section("SEC_2")# 删除节点中的键值config.remove_option('SEC_1', 'k10')config.write(open('/Users/wupeiqi/PycharmProjects/luffyCourse/day09/files/new.conf', 'w'))。
使⽤QSettings操作INI配置⽂件环境:Win10+VS2015+Qt5.9.8C++代码:// 配置⽂件:可执⾏路径\config\main.ini,如果没有config⼦⽬录会⾃动创建QSettings settings(QString("%1%2").arg(QCoreApplication::applicationDirPath(), "\\config\\main.ini"), QSettings::Format::IniFormat);settings.clear(); // 清除已有的所有配置,慎⽤settings.setValue("Key1", "Value1"); // 缺省Section是[General]settings.setValue("Key2", true);settings.setValue("Key3", "中⽂"); // 中⽂保存编码值\x4e2d\x6587settings.setValue("Section1/Key1", "Value1");settings.setValue("Section1/Key2", true);settings.setValue("Section1/Key3", "中⽂");settings.setValue("Section2/Key1", "Value1");settings.setValue("Section2/Key2", true);settings.setValue("Section2/Key3", "中⽂,Eng,\"Eng\"");QString s = settings.value("Key3").toString();LOG_INFO("值:" << s.toStdString().c_str());// 存取列表QList<QVariant> list1 = { 1, "A,B", "我,你" };settings.setValue("Section2/Key4", QVariant(list1));QList<QVariant> list2 = settings.value("Section2/Key4").toList();// 存取键值对QMap<QString, QVariant> map1 = { { "mapkey1", 1 },{ "mapkey2", "哈哈" } };settings.setValue("Section2/Key5", QVariant(map1));QMap<QString, QVariant> map2 = settings.value("Section2/Key5").toMap();对应INI⽂件:[General]Key1=Value1Key2=trueKey3=\x4e2d\x6587[Section1]Key1=Value1Key2=trueKey3=\x4e2d\x6587[Section2]Key1=Value1Key2=trueKey3="\x4e2d\x6587,Eng,\"Eng\""Key4=1, "A,B", "\x6211,\x4f60"Key5=@Variant(\0\0\0\b\0\0\0\x2\0\0\0\xe\0m\0\x61\0p\0k\0\x65\0y\0\x32\0\0\0\n\0\0\0\x4T\xc8T\xc8\0\0\0\xe\0m\0\x61\0p\0k\0\x65\0y\0\x31\0\0\0\x2\0\0\0\x1)。
C#如何实现完整的INI⽂件读写类作者: 魔法软糖⽇期: 2020-02-27引⾔*************************************.ini ⽂件是Initialization File的缩写,即配置⽂件。
是的系统所采⽤的存储格式。
它具有⽅便易⽤的特点,和注册表的键值有着类似的功能,各类应⽤程序也经常使⽤INI保存各种配置和选项。
在简单只需要读取的场合,调⽤WINDOWS API就⾏,但在复杂的需要可视化编辑时,就需要建⽴⾃⼰的处理类了。
如何实现⾃⼰的INI类⾸先我们需要了解◇ INI的格式◇典型INI⽂件;项⽬注释[.ShellClassInfo]InfoTip=有图标的⽂件夹;图标资源IconResource="C:\Windows\system32\SHELL32.dll",4#⽂件夹视图[ViewState]Mode=Vid=FolderType=General#尾部注释⼀个典型INI⽂件由节、注释和节下⾯的项组成,⽽项为键=值的形式。
INI⽂件的注释符号有两种,规范为;分号,实际有些地⽅⽤#井号。
◇保留注释为了在修改INI⽂件时不丢失任何信息,所以需要保存INI⽂件中所有有效元素、包括注释甚⾄是⽆效⾏。
为了实现这个⽬的,将所有注释和⽆效⾏都归属于它之后的有效元素。
以上⾯的desktop.ini为例,第⼀⾏ ;项⽬注释归属于[.ShellClassInfo]节第四⾏;图标资源归属于IconResource=项#⽂件夹视图归属于[ViewState]节最后的#尾部注释归属于整个INI⽂档的EndText◇ INIItem类表⽰INI⽂件中节点下⾯的项,它拥有三个属性:名称Name、值Value和注释Comment1///<summary>2///拥有名称、值和注释3///</summary>4public class INIItem {5///<summary>6///实例化INIItem。
1.定义一些变量Public IniFileName As String, vbNullString As String, maxSize As Long, section1 As String, section2 As String2.初始话这些变量Public Function initial()IniFileName = App.Path & "" & "config.ini"vbNullString = ""maxSize = 255section1 = "basics"section2 = "others"temp_str = String(255, 0) '建立缓冲区End Function3.声明INI函数Public Declare Function GetPrivateProfileInt Lib "kernel32" Alias "GetPrivateProfileIntA" ( _ByVal lpApplicationName As String, _ByVal lpKeyName As String, _ByVal nDefault As Long, _ByVal lpFileName As String) As LongPublic Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" ( _ByVal lpApplicationName As String, _ByVal lpKeyName As Any, _ByVal lpDefault As String, _ByVal lpReturnedString As String, _ByVal nSize As Long, _ByVal lpFileName As String) As LongPublic Declare Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" ( _ByVal lpApplicationName As String, _ByVal lpKeyName As Any, _ByVal lpString As Any, _ByVal lpFileName As String) As Long4.调用函数dim source as stringGetPrivateProfileString section1, "source", vbNullString, temp_str, maxSize, IniFileNamesource = Mid(temp_str, 0, 5) '缓冲区长度249,直接去匹配是不可以的,需要首先提取出有效字符xpos.Text = GetPrivateProfileInt(section1, "xpos", 1, IniFileName)dim a as intergera = GetPrivateProfileInt(section1, "auto", 1, IniFileName) WritePrivateProfileString section1, "auto", "0", IniFileName下一个例子Option ExplicitPrivate Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" ( _ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpDefault As String, _ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String) As LongPrivate Declare Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" ( _ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpString As Any, _ByVal lpFileName As String) As LongPrivate Function GetIni(ByVal ApplicationName As String, ByVal KeyName As String, ByVal FileName As String) As StringDim Buff As String, TmpStr As StringBuff = String(1024, 0)Call GetPrivateProfileString(ApplicationName, KeyName, "", Buff, Len(Buff) + 1, FileName)If Asc(Mid(Buff, 1, 1)) = 0 Then GetIni = "": Exit FunctionDim I As IntegerFor I = 2 To Len(Buff)If Asc(Mid(Buff, I, 1)) = 0 Then TmpStr = Mid(Buff, 1, I - 1)NextIf TmpStr = "" Then TmpStr = BuffGetIni = TmpStrEnd FunctionPrivate Function PutIni(ByVal ApplicationName As String, ByVal KeyName As String, ByVal Str As String, ByVal FileName As String) As Long WritePrivateProfileString ApplicationName, KeyName, Str, FileNameEnd FunctionPrivate Function DelIni(ByVal ApplicationName As String, ByVal KeyName As String, ByVal FileName As String) As LongWritePrivateProfileString ApplicationName, KeyName, 0&, FileNameEnd FunctionPrivate Sub Form_Load()Shell (GetIni("lujing", "pa", "INI文件的路径及名称.ini") & "\" & GetIni("lujing", "pa1", "INI文件的路径及名称.ini"))End Sub再次讲解这是API函数,使用前必须在公共部分定义,可以建公共模块,也可以在窗体最上面写.代码:Public Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String) As LongPublic Declare Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" (ByVal lpApplicationName As String, ByVallpKeyName As Any, ByVal lpString As Any, ByVal lpFileName As String) As Long然后GetPrivateProfileString WritePrivateProfileString 这两个函数就可以用了.读取和写入代码如下Private Sub SetIniS(ByVal SectionName As String, ByVal KeyWord As String, ByVal ValStr As String)Dim res%res% = WritePrivateProfileString(SectionName, KeyWord, ValStr, "C:\123.ini") End SubPrivate Function GetIniS(ByVal SectionName As String, ByVal KeyWord As String, ByVal DefString As String) As StringDim llLen As LongDim ResultString As StringResultString = Space(100)llLen = GetPrivateProfileString(SectionName, KeyWord, DefString, ResultString, 100, "C:\123.ini")GetIniS = Mid(ResultString, 1, llLen)End Function。
INI文件操作类作者凯征在网上看了一些INI文件读写的一些源码,总是感觉少了些什么。
于是自己编了一个INI文件操作类拿出来和大家分享,希望有所帮助。
本类的限制1.INI文件必须用段名开头如:[Section1]2.在赋值符等号的两边必须各加一个空格如:“= ”3.不支持注释符“;”4.只支持字符型键值输入,整型需转换本类的功能1.打开INI文件时,如果文件不存在就创建它2.设置键值如果键或段不存在就添加该段和键。
3.读取键值4.遍历段和键5.删除段和键6.保存文件我用该类编写了一个INI文件编辑器来对应该类的操作,如果有需要可以到以下网址下载该编辑器的源码和实例。
/detail/linkaizheng/4510641INI文件操作类源码#region引用声明using System;using System.IO;using System.Windows.Forms;#endregion#region Ini文件操作空间namespace IniFileEdit{#region定义类型#region定义行类型枚举///<summary>/// IniFileLineType枚举用于记录行类型和状态///</summary>public enum IniFileLineType{Error, // 发生错误Null, // 没有有效的行 Section, // 行内容为段名 Key, // 行内容为键 }#endregion#region段和键定位的索引结构///<summary>///定义用于段和键定位的索引结构///</summary>public struct Index{private int start; // 起始位置private int length; // 长度public int Start{get { return start; }set { start = value; }}public int Length{get { return length; }set { length = value; }}}#endregion#region定义行结构///<summary>/// IniFileLineMatter结构在遍历Ini文件时用于保存每行的内容和定位信息///</summary>public struct IniFileLineMatter{private int start; // 行起始位置private int length; // 行长度private IniFileLineType linetype; // 行类型private string sectionorkeyname; // 段名或键名private string keyvalue; // 字符串型键值public int Start { get { return start; } set { start = value; } }public int Length { get { return length; } set { length = value; } }public IniFileLineType LineType { get { return linetype; } set { linetype = value; } } public string SectionOrKeyName { get{ return sectionorkeyname; } set{ sectionorkeyname = value; } }public string KeyValue { get { return keyvalue; } set { keyvalue = value; } }}#endregion#region文件操作状态枚举///<summary>///定义用于确定Ini文件操作状态的枚举///</summary>public enum IniFileStateCode{Error, // 文件路径错误Create, // 已建立了一个空的Ini文件Null, // 文件为空文件Load, // 文件已加载Updata // 缓冲区中的内容已更新,文件需要保存}#endregion#endregion#region Ini文件操作类public class IniFileOperate{#region定义变量// 定义用于保存Ini文件全路径名称的变量string IniFileAllPath;// 定义Ini文件在内存中的操作缓冲区string StrIniFileBuf;// 定义用于保存Ini文件操作状态的变量IniFileStateCode IniFileState;public IniFileStateCode FileState { get { return IniFileState; } }#endregion#region公开的成员方法#region构造方法///<summary>///构造方法///</summary>///<param name="IniFilePathName">用于输入Ini文件的路径和名称,可以使用全路径名称,也可以使用相对路径名称</param>public IniFileOperate(string iniFilePathName){IniFileAllPath = iniFilePathName;try{// 判断文件是否存在if (File.Exists(IniFileAllPath) == false){// 不存在就创建一个空的Ini文件。
FileStream fs = File.Create(IniFileAllPath);fs.Close();StrIniFileBuf = "";IniFileState = IniFileStateCode.Create;}else{// 存在就将文件加载到缓冲区StrIniFileBuf = File.ReadAllText(IniFileAllPath);if (StrIniFileBuf.Length == 0)IniFileState = IniFileStateCode.Null;elseIniFileState = IniFileStateCode.Load;}}catch (IOException IOEx){// 发生异常,显示异常信息String Str = '\"' + IniFileAllPath + '\"' + "文件操作异常!";IniFileState = IniFileStateCode.Error;MessageBox.Show(IOEx.ToString(),Str,MessageBoxButtons.OK,MessageBoxIcon.Error,MessageBoxDefaultButton.Button1,MessageBoxOptions.DefaultDesktopOnly);}}#endregion#region设置字符串型键值///<summary>///设置字符串型键值方法///</summary>///<param name="section">段名</param>///<param name="key">键名</param>///<param name="value">键值</param>public void SetStringKeyValue(string section, string key, string value) {// 判断输入是否合法if (SectionAndKeyNameCheckUp(section, key) == false)return;if (value.Length == 0){MessageBox.Show("键值不能为空","输入错误!",MessageBoxButtons.OK,MessageBoxIcon.Error,MessageBoxDefaultButton.Button1,MessageBoxOptions.DefaultDesktopOnly);return;}// 判断Ini文件是否为空文件if (StrIniFileBuf.Length == 0)// 是空文件,直接添加段和键行AddNewSection(section, key, value);else{// 不是空文件,先查找段Index SectionIndex = GetSectionIndex(section);// 判断是否找到了该段名if (SectionIndex.Start < 0)// 没有找到段名,在文件最后添加段和键行AddNewSection(section, key, value);else{// 找到了该段名,查找键位置Index KeyIndex = GetKeyIndex(SectionIndex, key);// 判断是否找到了该键位置if (KeyIndex.Start < 0){// 没有找到,在该段最后插入新键StrIniFileBuf = StrIniFileBuf.Insert(SectionIndex.Start + SectionIndex.Length, CombiningKeyLine(key, value));IniFileState = IniFileStateCode.Updata;}else{// 找到了该键,取得原键值string OldKeyValue = StrIniFileBuf.Substring(KeyIndex.Start, KeyIndex.Length);// 判断键值是否相同if (value != OldKeyValue){// 不同,修改为新键值string NewStrIniFileBuf = StrIniFileBuf.Substring(0, KeyIndex.Start);NewStrIniFileBuf += value;NewStrIniFileBuf += StrIniFileBuf.Substring(KeyIndex.Start + OldKeyValue.Length, StrIniFileBuf.Length - (KeyIndex.Start + OldKeyValue.Length));StrIniFileBuf = NewStrIniFileBuf;IniFileState = IniFileStateCode.Updata;}}}}}#endregion#region取得字符串型键值///<summary>///取得字符串型键值方法///</summary>///<param name="section">段名</param>///<param name="key">键名</param>///<returns>返回键值</returns>public string GetStringKeyValue(string section, string key){// 判断输入是否合法if (SectionAndKeyNameCheckUp(section, key) == false)return"";// 查找段名Index SectionIndex = GetSectionIndex(section);// 判断是否找到了该段if (SectionIndex.Start < 0)// 没有找到,返回空字符串return"";else{// 找到了该段,在该段中查找键名Index KeyIndex = GetKeyIndex(SectionIndex, key);// 判断是否找到了该键名if (KeyIndex.Start < 0)// 没有找到,返回空字符串return"";else// 找到了该键名,返回键值return StrIniFileBuf.Substring(KeyIndex.Start, KeyIndex.Length); }}#endregion#region删除键public void DeleteKey(string section, string key){Index index = GetSectionIndex(section);index = GetKeyIndex(index, key);int namelength = key.Length + 5;index.Start -= namelength;index.Length += namelength;Delete(index);}#endregion#region删除段public void DeleteSection(string section){Index index = GetSectionIndex(section);int namelength = section.Length + 4;index.Start -= namelength;index.Length += namelength;Delete(index);}#endregion#region保存Ini文件///<summary>///保存Ini文件方法///在对Ini文件的所有写操作完成后,调用此方法将缓冲区中的内容保存至文件。