ini文件
什么是ini文件
NI(Initialization File)是微软Windows操作系统中的文件扩展名。这些字母表示初始化。正如该术语所表示的,INI文件被用来对操作系统或特定程序初始化或进行参数设置。在项目也会将一些配置信息存于ini文件,所以读取配置文件是项目中不可缺少的一部分。由于ini只有节和参数比较简单,在Qt中又有QSettings类使得更加便捷。
格式
INI文件由节、键、值组成
节 [section]
参数 (键=值) name=value
注解 注解使用分号表示(;)。在分号后面的文字,直到该行结尾都全部为注解。如; comment textINI文件的数据格式的例子(配置文件的内容) [Section1 Name]
KeyName1=value1 KeyName2=value2 ... [Section2 Name] KeyName21=value21 KeyName22=value22
其中:
[Section1 Name]用来表示一个段落。
需要的参数
头文件:#include
qmake: QT += core; (一般的qt工程默认会配置core)
需要了解的API
构造函数:QSettings(const QString &fileName, Format format, QObject *parent = Q_NULLPTR)
fileName:文件名(包括路径,注意转义)
Format:是枚举类型。该enum类型指定QSettings使用的存储格式。
parent: 父类
下图Qt官方文档原文
中文对照
这里的话我们一般用的是QSettings::IniFormat。
设置参数的值: void setValue(const QString &key, const QVariant &value)
获取参数的值: QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const
这里defaultValue意思是如果未找到该参数的值将会返回你给你默认值,否则返回空或者0。
单例
单例有其独有的使用场景,一般是对于那些业务逻辑上限定不能多例只能单例的情况,例如:类似于计数器之类的存在,一般都需要使用一个实例来进行记录,若多例计数则会不准确。 其实单例就是那些很明显的使用场合,没有之前学习的那些模式所使用的复杂场景,只要你需要使用单例,那你就使用单例,简单易理解。
所以读取配置文件也需要设计成单例模式。主要分为单线程使用和多线程使用。下面列出了俩种的实例。
单线程实例
#pragma once #include <thread> #include <mutex> #include <iostream> using namespace std; class Singleton { public: static Singleton* NewObject()//无参版本 { if (sm_obj == nullptr) { sm_obj = new Singleton; } return sm_obj; } static Singleton* NewObject(int a, char b, double c)//有参版本 { if (sm_obj == nullptr) { sm_obj = new Singleton(a, b, c); } return sm_obj; } void DelObject() { if (Singleton::sm_obj != nullptr) { delete sm_obj; sm_obj = nullptr; } } private: Singleton() { m_a = 0; m_b = 0; m_c = 0; } Singleton(int a, char b, double c) { m_a = a; m_b = b; m_c = c; } ~Singleton(){ } Singleton(const Singleton& other){ } void operator=(const Singleton* ohter){ } private: static Singleton* sm_obj; int m_a; char m_b; double m_c; }; Singleton* Singleton::sm_obj = nullptr;//懒汉模式,以时间换空间 //Singleton* Singleton::sm_obj = new Singleton;//饿汉模式,以空间换时间
多线程实例
#pragma once #include <thread> #include <mutex> #include <iostream> using namespace std; mutex g_m;//创建锁 class Singleton { public: static Singleton* NewObject()//无参版本 { //双重校验锁 if (sm_obj == nullptr)//增加效率 { 加锁防止多线程同时创建造成内存泄漏 lock_guard<mutex> lg(g_m);//守卫锁,也叫自解锁。防止异常死锁 //g_m.lock(); if (sm_obj == nullptr) { sm_obj = new Singleton; } //g_m.unlock(); } return sm_obj; } static Singleton* NewObject(int a, char b, double c)//有参版本 { //双重校验锁 if (sm_obj == nullptr)//增加效率 { //加锁防止多线程同时创建造成内存泄漏 //守卫锁,也叫自解锁。防止异常死锁 lock_guard<mutex> lg(g_m); if (sm_obj == nullptr) { sm_obj = new Singleton(a, b, c); } } return sm_obj; } void DelObject() { if (Singleton::sm_obj != nullptr) { delete sm_obj; sm_obj = nullptr; } } private: Singleton() { m_a = 0; m_b = 0; m_c = 0; } Singleton(int a, char b, double c) { m_a = a; m_b = b; m_c = c; } ~Singleton(){ } Singleton(const Singleton& other){ } void operator=(const Singleton* ohter){ } private: static Singleton* sm_obj; int m_a; char m_b; double m_c; }; Singleton* Singleton::sm_obj = nullptr;//懒汉模式,以时间换空间 //Singleton* Singleton::sm_obj = new Singleton;//饿汉模式,以空间换时间
设计一个读取ini文件的类
首先正常创建一个qt的工程,有无ui界面都可以。如下图。
然后创建一个1.ini文件。内容可以照抄下面的,[]是节的固定格式,里面的system就是节的名称。下面就ip=121.52.52.5就是赋值。
AppSettings类
头文件
#ifndef APPSETTINGS_H #define APPSETTINGS_H #include <string> #include <QSettings> #include <QMutex> #include <QMutexLocker> class AppSettings { public: static AppSettings* Instance(); void Init(QString fileName); QString GetIp() const; void SetIp(QString ip); private: AppSettings(); ~AppSettings(); private: QSettings* settings; static AppSettings* sm_obj; }; #endif // APPSETTINGS_H
源文件
#include "appsettings.h" QMutex g_m; AppSettings* AppSettings::sm_obj = nullptr;//懒汉模式,以时间换空间 AppSettings *AppSettings::Instance() { if(sm_obj == nullptr) { QMutexLocker lg(&g_m); if(sm_obj == nullptr) { sm_obj = new AppSettings(); } } return sm_obj; } void AppSettings::Init(QString fileName) { settings = new QSettings(fileName, QSettings::IniFormat); settings->setIniCodec("GBK"); } QString AppSettings::GetIp() const { return settings->value("system/ip", "127.0.0.1").toString(); } void AppSettings::SetIp(QString ip) { settings->setValue("system/ip", ip); } AppSettings::AppSettings() { } AppSettings::~AppSettings() { }
调用代码
AppSettings::Instance()->Init("1.ini"); AppSettings::Instance()->SetIp("12.52.52.5"); // 给Ip赋值 qDebug() << AppSettings::Instance()->GetIp(); // 获取Ip的值
运行结果