• 很多桌面软件在打开的时候,都有记住密码等选项,而且在没联网的情况下也能读取,这个是因为,它把配置信息写在本地,每次打开之前先读取本地的配置信息,即可加载相关配置,那么在这种情况下,可以封装一个配置类,方便我们以后复用。

  • 先看一下本地配置信息大概的结构
    在这里插入图片描述
    这是Windows文本是随机的一个本地配置信息
    可以看出,配置文本结构主要由[属性名]键=值的方式构成
    然后基本是以.ini为后缀的形式构成。根据这些基础信息,我们就很容易写我们自己的配置文本类
    接下来是实际代码

头文件部分:

#include <QFile>
#include <QString>
#include <QDebug>
#include <QMutex>

// 配置文件类
class QIniConfig{
public:
    QIniConfig();
    ~QIniConfig();

    static QIniConfig* GetInstance();
    bool Init(QString file_name);
    bool ConfigAttributeName(QString attr_name); //配置属性名
    bool WriteToConfig(QString key_,QString val_); //写入配置文件
    bool IsConfigAttributeName();//判断是否有[];从而判断是否已经设置配置属性名
    QString ReadValue(QString key_,QString attr_=""); //读取key的值 //没找到则返回""
    bool IsConfigStr(QString str_); // 判断是否为配置字符
    QString GetConfigName(QString str_); //从配置名格式中获取属性名[ii] 获取ii
private:
    bool m_b_init_file; // 是否初始化文件
    QFile* m_ini_file; //配置文件的句柄
    bool m_b_ConfigName; //是否配置属性名
    static QIniConfig* m_iniConfig;
    QString m_filename; //配置文件名:
};

  • 实现代码:
#include "QIniConfig.h"

QIniConfig::QIniConfig():m_b_init_file(false),m_ini_file(nullptr),m_b_ConfigName(false),m_filename("")
{
    qDebug() << "Init Config";
}

QIniConfig* QIniConfig::m_iniConfig = nullptr;

QIniConfig* QIniConfig::GetInstance()
{
    if(!m_iniConfig)
    {
        m_iniConfig = new QIniConfig();
        return m_iniConfig;
    }
    return m_iniConfig;
}

QIniConfig::~QIniConfig()
{
   qDebug() << "Destroy Config";
   if(m_ini_file)
   {
       m_ini_file->close();
       delete m_ini_file;
       m_ini_file = nullptr;
   }
}

bool QIniConfig::Init(QString file_name)
{
    if(file_name.size()<1)
    {
        return false;
    }
    m_ini_file = new QFile(file_name);
    if(m_ini_file)
    {
        m_filename = file_name;
        m_b_init_file = true; // 说明初始化成功
        m_ini_file->open(QIODevice::ReadWrite|QIODevice::Append); //支持读写操作:往后写
        IsConfigAttributeName();
        return true;
    }
    return false;
}

// 配置属性名 [attributeName]形式
bool QIniConfig::ConfigAttributeName(QString attr_name)
{
    if(attr_name.size()<1)
    {
        return false;
    }
    if(!m_ini_file)
    {
        return false;
    }
    QString str_attribute = "[" + attr_name + "]" +"\n"; // 需要添加换行符,方便读取
    m_ini_file->write(str_attribute.toUtf8());
    m_b_ConfigName = true; //配置属性名成功
    return true;
}

bool QIniConfig::WriteToConfig(QString key_, QString val_)
{
    if(!m_ini_file)
    {
       return false;
    }
    if(!m_b_ConfigName)
    {
        return false;
    }
    QString str_key_val = key_ +"="+val_+"\n";
    m_ini_file->write(str_key_val.toUtf8());//写入
    return true;
}

bool QIniConfig::IsConfigAttributeName()
{
    QFile file_(m_filename);
    file_.open(QIODevice::ReadOnly);
    // 读取第一行即可[];//主要判断是否有[]
     QByteArray line = file_.readLine();
     QString str(line);
      qDebug() <<  str;
     if(str.size() < 1)
     {
         m_b_ConfigName = false;
     }
     else{
        if(str[0]=="[" && str[str.size()-2] == "]")
        {
            m_b_ConfigName = true;
        }
     }
    file_.close();
    return m_b_ConfigName;
}

QString QIniConfig::ReadValue(QString key_, QString attr_)
{
    QFile file_(m_filename);
    file_.open(QIODevice::ReadOnly);
    bool b_Found_Once = false;
    if(attr_ == "")
    {
        //等于空的情况,比较好处理,直接按行搜索即可
        while(!file_.atEnd())
        {
            QByteArray array_ = file_.readLine();
            QString str_(array_);
            if(str_.contains("="))
            {
                // 进行判断处理
                 str_.chop(1);//去掉空格
                 QStringList str_list = str_.split("=");
                 if(str_list[0] == key_)
                 {
                     qDebug() << "value is " << str_list[1];
                     file_.close();
                     return str_list[1];
                 }
            }
        }
        file_.close();
        return "";
    }
    else{
        while(!file_.atEnd())
        {

            QByteArray array_ = file_.readLine();
            QString str_(array_);
            // 此处为属性名
            if(IsConfigStr(str_))
            {
              if(b_Found_Once)
              {
                  file_.close();
                  return "";
              }
              QString str_configs =  GetConfigName(str_);
              if(str_configs == attr_)
              {
                  b_Found_Once = true;
                  qDebug() << "find";
              }
            }
            // 此处为key = value形式
            if(b_Found_Once)
            {
                if(str_.contains("="))
                {
                    // 进行判断处理
                     str_.chop(1);//去掉空格
                     QStringList str_list = str_.split("=");
                     if(str_list[0] == key_)
                     {
                          qDebug() << "value is " << str_list[1];
                         file_.close();
                         return str_list[1];
                     }
                }
            }
        }

        file_.close();
        return "";
    }
    file_.close();
    return "";

}

bool QIniConfig::IsConfigStr(QString str_)
{
    if(str_.size() < 3)
    {
        return false;
    }
    if(str_[0]=="[" && str_[str_.size()-2] == "]")
    {
        return true;
    }
    return false;
}

QString QIniConfig::GetConfigName(QString str_)
{
    str_.chop(1);
    QString strss = str_.replace("[","");
    QString str_configName = strss.replace("]","");
    return str_configName;

}

  • 由于代码基本上都有注释,所以也就可以直接讲一下它的调用方法
    // 初始化配置文件:{文件名}
    QIniConfig::GetInstance()->Init(ini_path);
    
    // 配置属性名部分
    QIniConfig::GetInstance()->ConfigAttributeName("test");
    //写入相关的配置信息
    QIniConfig::GetInstance()->WriteToConfig("keys","world");
    //读取值
    QString value_ = QIniConfig::GetInstance()->ReadValue("keys","test");

比较方便,读取值部分可以有两种方式,一种是全局读取,即不根据属性名读取,另一种是根据属性名读取的方式,针对于相应的使用场景大家可以灵活调用。

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐