【Qt】解析配置文件INI

        INI文件的语法简单,结构清晰,便于阅读。网上有很多INI文件相关的资料,但是很少有看到说明INI文件的起源和发展的文章。其实我也好奇这点,接下来,我就先介绍INI文件的起源和发展,然后介绍INI文件的语法,以及Qt中如何读取和编辑INI文件。   

INI文件的起源和发展 

        INI文件的概念最早由Microsoft在20世纪80年代提出并使用在早期的Windows操作系统中。INI文件的设计初衷是为了存储应用程序的配置数据。“INI"一词是"Initialization”(初始化)的缩写。

        当时的Windows操作系统并没有统一的配置文件格式,每个应用程序都需要自己实现配置文件的读取和写入。为了解决这个问题,Microsoft引入了INI文件作为一种通用的配置文件格式,以简单的键值对的方式存储配置数据。

        INI文件的设计初衷是为了提供一种轻量级、易于编辑和解析的配置文件格式。之后,INI文件成为了Windows系统中常见的配置文件格式,并被许多应用程序广泛采用。

        虽然INI文件最早由Microsoft引入,并在Windows系统中得到广泛应用,但INI文件的概念和实现方式也被其他操作系统和应用程序所采用和扩展。不同的操作系统和应用程序可能会对INI文件有些许的差异和扩展,但基本的键值对结构和语法规则基本保持一致。

INI文件的作用

        INI文件(Initialization File)是一种用于存储配置数据的文本文件格式。它通常以简单的键值对(Key-Value)的形式组织数据,用于保存应用程序的各种设置和选项。例如:数据库连接配置、网络设置、界面风格、语言选择等。通过读取和修改INI文件,用户和开发者可以轻松地配置和个性化应用程序,满足特定的需求。

INI文件的语法

        INI文件的语法非常简单,它是以文本形式存储配置数据的一种格式。下面是INI文件的常见语法规则:


(Section)
节用方括号[ ]括起来,用于区分不同的配置项,例如:[section1]。节名可以是任何字符和数字的组合,但一般建议使用有意义的名称。
键值对
(key-value)
键值对是配置项的基本元素,用于存储具体的配置数据。键(Key)和值(Value)之间用等号(=)或冒号(:)分隔。例如:Key1=Value1
注释
(Comment)
注释用来添加对配置项的说明,不会被程序读取。在INI文件中,以分号(;)或井号(#)开头的行都被视为注释。例如:; 我是注释我是注释

空行

(Blank Line)

空行不包含任何内容,通常用于提高文件的可读性。
字符串
(string)
 键和值可以是任何文本,包括字母、数字、标点符号等。字符串可以使用引号(单引号或双引号)括起来,也可以不括起来。

注意:INI文件不一定都是以  .ini  为文件后缀名。其他常见的后缀名还有:.cfg  .conf

INI文件的后缀名并没有严格的规定,不同的应用程序或操作系统可能会使用不同的后缀名。因此,在具体的应用程序或系统中,可能会存在其他的INI文件后缀名。

关于嵌套节

        在标准的INI文件格式中,并没有直接支持嵌套节的概念。每个节都是独立的,并且没有层次结构。

        然而,一些解析INI文件的库或工具提供了对嵌套节的支持,通过特定的约定或语法扩展来模拟嵌套的结构。这样可以在节内部创建子节或子命名空间,以更好地组织和表示配置数据。

        例如,可以使用点号 . 或大括号 {} 来表示嵌套的节。下面是一个示例:

[Section1]
Key1=Value1

[Section1.Subsection1]
Key2=Value2

[Section1.Subsection2]
Key3=Value3

        使用这种约定或语法,可以在Section1节内部创建子节SubSection1和SubSection2,从而实现嵌套的节结构。

        需要注意的是,嵌套节的使用可能会依赖于具体的解析器或库,不同的工具对语法的支持和解析方式可能有所不同。因此,在使用嵌套节时,应该遵循相应工具的文档和准则,并确保解析器能够正确解释INI文件中的嵌套节。

        这里不讨论嵌套节。

INI文件解析

        Qt中有QSettings默认支持INI文件,除了INI文件之外,QSettings还支持Json、XML、注册表(windows特定)、SQLite数据库格式等。QSettings::Format  枚举类型中包含了QSettings支持的文件格式。

        在电脑中找到了一个迅雷的配置文件,内容如下:

[MainFrame]
ExitType=normal
ExitState=normal
MainWndLastWidth=1060
MainWndLastHeight=650

[MainBody]
ExitType=normal
ExitState=normal
MainWndLastWidth=1120
MainWndLastHeight=680

void initest::iniRead(){
    QSettings settings("路径/Thunder.ini",QSettings::IniFormat);

    qDebug()<<settings.allKeys()<<settings.fileName();
    qDebug()<<settings.status();

    settings.beginGroup("MainFrame");
    QString frameExitType=settings.value("ExitType").toString();
    QString frameExitState=settings.value("ExitState").toString();
    int frameMainWndLastWidth=settings.value("MainWndLastWidth").toInt();
    int frameMainWndLastHeight=settings.value("MainWndLastHeight").toInt();
    qDebug()<<"frameExitType:"<<frameExitType;
    qDebug()<<"frameExitState:"<<frameExitState;
    qDebug()<<"frameMainWndLastWidth:"<<frameMainWndLastWidth;
    qDebug()<<"frameMainWndLastHeight:"<<frameMainWndLastHeight;
    settings.endGroup();

    QString bodyExitType=settings.value("MainBody/ExitType").toString();
    QString bodyExitState=settings.value("MainBody/ExitState").toString();
    int bodyMainWndLastWidth=settings.value("MainBody/MainWndLastWidth").toInt();
    int bodyMainWndLastHeight=settings.value("MainBody/MainWndLastHeight").toInt();
    qDebug()<<"bodyExitType:"<<bodyExitType;
    qDebug()<<"bodyExitState:"<<bodyExitState;
    qDebug()<<"bodyMainWndLastWidth:"<<bodyMainWndLastWidth;
    qDebug()<<"bodyMainWndLastHeight:"<<bodyMainWndLastHeight;

    //可以看到使用beginGroup再使用其中的键查找值和直接使用 组名/键 效果是一样的
}

运行结果:

QList("MainBody/ExitState", "MainBody/ExitType", "MainBody/MainWndLastHeight", "MainBody/MainWndLastWidth", "MainFrame/ExitState", "MainFrame/ExitType", "MainFrame/MainWndLastHeight", "MainFrame/MainWndLastWidth") "E:/000CProjects/SQLTest/SQLTest/ini/Thunder.ini"
QSettings::NoError
frameExitType: "normal"
frameExitState: "normal"
frameMainWndLastWidth: 1060
frameMainWndLastHeight: 650
bodyExitType: "normal"
bodyExitState: "normal"
bodyMainWndLastWidth:1120
bodyMainWndLastHeight: 680

写(创建)

void initest::iniWrite(){
    QSettings settings("路径/Thunder1.ini",QSettings::IniFormat);

    settings.beginGroup("MainFrame");
    settings.setValue("ExitType","normal");
    settings.setValue("ExitState","normal");
    settings.setValue("MainWndLastWidth",1060);
    settings.setValue("MainWndLastHeight",650);
    settings.endGroup();

    settings.setValue("BodyFrame/ExitType","normal");
    settings.setValue("BodyFrame/ExitState","normal");
    settings.setValue("BodyFrame/MainWndLastWidth",1120);
    settings.setValue("BodyFrame/MainWndLastHeight",680);

    settings.sync();
}

运行结果:

 修改

void initest::iniModify(){
    QSettings settings(GLOBAL::INIPath()+"/Thunder.ini",QSettings::IniFormat);

    settings.beginGroup("MainFrame");
    settings.setValue("MainWndLastWidth",666);
    settings.endGroup();
    settings.setValue("MainBody/MainWndLastHeight",888);

    settings.sync();
}

运行结果:

        通过上面的测试,可以看出,在setValue时,如果该键值对存在,就修改原有的值,如果不存在就新建键值对。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值