【C++】手搓读写properties文件源码

【C++】手搓读写properties文件源码

思路

properties文件实际上就是键值对的一种形式,用等号连接键和值。c++中和键值对最贴切的就是STL中的map了。所以我使用map作为properties的实际内存存储,同时为了方便使用,另外多一个set类型的字段记录所有的key。大致流程为:

1、逐行扫描文件内容;

2、过滤注释(#后面的为注释);

3、根据等号切割key和value;

4、保存key和value到map中;

需求:

1、当key没有值时:可以设定个默认值

2、读取文件时只有KEY没哟默认值会报错,添加一个默认值给该KEY

3、修改KEY的值时并保存到文件中

properties.h 头文件

cpp 复制代码
/**
  ******************************************************************************
  * @file           : properties.h
  * @author         : CircleDBA
  * @mail           : [email protected]
  * @blog           : circle-dba.blog.csdn.net
  * @date           : 24-5-8
  ******************************************************************************
  */


#ifndef KINGBASEMANAGERTOOLS_PROPERTIES_H
#define KINGBASEMANAGERTOOLS_PROPERTIES_H

#include <iostream>
#include <fstream>
#include <map>
#include <string>
#include <algorithm>
#include <sstream>
#include <vector>
#include <set>
#include <filesystem>

using namespace std;

namespace Circle {

    class properties {
    private:
        string config_path;
        map<string, string>* props = nullptr;
        set<string>* keys = nullptr;

        void trim(string& s);
        vector<string> split(const string& str, char pattern);
    public:
        properties();
        virtual ~properties();
        void file(boost::filesystem::path path);
        bool is_exists();
        bool load(std::string defaultValue);
        bool load(){load("None");};
        set<string>* getKeys() const;
        map<string, string>* getProps() const;
        string getValue(const string& key,const string& defaultValue);
        bool setValue(const string& key,const string& Value);
    };

} // Circle

#endif //KINGBASEMANAGERTOOLS_PROPERTIES_H

properties.cpp 文件

cpp 复制代码
/**
  ******************************************************************************
  * @file           : properties.cpp
  * @author         : CircleDBA
  * @mail           : [email protected]
  * @blog           : circle-dba.blog.csdn.net
  * @date           : 24-5-8
  ******************************************************************************
  */


#include "properties.h"

namespace fs = std::filesystem;

Circle::properties::properties() {
    this->props = new map<string, string>();
    this->keys = new set<string>();
}

Circle::properties::~properties() {
    delete props;
    delete keys;

}
//设置配置文件路径
void Circle::properties::file(std::string path){
    this->config_path = path;
}
//判断配置文件是否存在
bool Circle::properties::is_exists(){
    return fs::exists(this->config_path);
}

void Circle::properties::trim(string& s)
{
    if (!s.empty())
    {
        s.erase(0, s.find_first_not_of(" "));
        s.erase(s.find_last_not_of(" ") + 1);
    }

}

vector<string> Circle::properties::split(const string& str, char pattern)
{
    vector<string> res;
    stringstream input(str);
    string temp;
    while (getline(input, temp, pattern))
    {
        res.push_back(temp);
    }
    return res;
}

bool Circle::properties::load(std::string defaultValue = "None"){
    std::ifstream file(this->config_path);
    std::string line;
    while (getline(file, line)) {
        trim(line);
        //去空行
        if (line.empty() || line == "\r" || line[0] == '#')
        {
            continue;
        }
        //处理等号后为空的配置
        vector<string> res = split(line, '=');
        if (res.size() < 2)
        {
            res[1] = defaultValue;
        }
        int t = res[1].find("#");
        if (t != string::npos) {
            res[1].erase(t);
        }
        for_each(res.begin(), res.end(), [=](string& s)mutable {
            trim(s);
        });
        props->insert(make_pair(res[0], res[1]));
        keys->insert(res[0]);
    }
    file.close();
}

set<string>* Circle::properties::getKeys() const {
    return keys;
}

map<string, string>* Circle::properties::getProps() const {
    return this->props;
}

string Circle::properties::getValue(const string& key,const string& defaultValue) {
    if (props->find(key) == props->end())
    {
        return defaultValue;
    }
    string value =this->props->at(key);
    return value;
}

bool Circle::properties::setValue(const string& key,const string& Value) {
    if (props->find(key) == props->end())
    {
        this->props->insert(make_pair(key, Value));
    }else{
        props->at(key) = Value;
    }

    std::ofstream outFile(this->config_path);
    for (const auto& pair : *props) {
        outFile << pair.first << " = " << pair.second << std::endl;
    }
    return true;
}

example.properties 示例代码

cpp 复制代码
key1 = value1
key3 = value3
key5 = aaa
log.key4 = value4

运行例子:

cpp 复制代码
#include "properties.h"
main(){
	 std::string configPaht = "example.properties"
	 Circle::properties properties;
     properties.file(configPaht);
     //判断配置文件是否存在
     if(properties.is_exists()){
     	//读取配置文件写入props,keys
     	properties.load();
     	//读取键值,如果不存在就返回默认值defaultValue
     	properties.getValue("key5","defaultValue");
     	//设置键值并写入文件
     	properties.setValue("key5","aaa");
     }
}

参考文章

C++读取Properties的工具类

相关推荐
lsnm5 分钟前
【LINUX操作系统】线程操作
linux·jvm·c++·ubuntu·centos·gnu
小羊Linux客栈11 分钟前
Python小程序:上班该做点摸鱼的事情
开发语言·python·小程序·游戏程序
咛辉17 分钟前
如何搭建spark yarn 模式的集群集群。
开发语言
zhengtianzuo33 分钟前
043-代码味道-循环依赖
c++
CoderCodingNo1 小时前
【GESP】C++三级练习 luogu-B2118 验证子串
开发语言·c++
小彭努力中1 小时前
9.Three.js中 ArrayCamera 多视角相机详解+示例代码
开发语言·前端·javascript·vue.js·数码相机·ecmascript·webgl
学习中的码虫1 小时前
c#栈及其应用
开发语言·c#
bai_lan_ya1 小时前
C语言中结构体的字节对齐的应用
c语言·开发语言
小陈092 小时前
Java后端图形验证码的使用
java·开发语言·状态模式