007-nlohmann/json 项目应用-C++开源库108杰
本课为 fswatch(第一“杰”)的示例项目加上对配置文件读取的支持,同时借助 第三“杰” CLI11 的支持,完美实现命令行参数与配置文件的逻辑统一。
012-nlohmann/json-4-项目应用
项目基于原有的 CMake 项目 HelloFSWatch 修改。
-
CMakeLists.txt :该文件基于原项目,没有任何改动。
-
.vscode/setting.json ,改动如下:
{ "cmake.debugConfig": {"cwd": "${workspaceFolder}","args": ["-m", "3", "--log-level", "info"],"externalConsole": false}
}
重点:
① args字段:添加命令行参数;
② cwd 字段:设置程序在项目根目录下运行(而在程序所在的 build 子目录内)。
- myConfig.json 测试用的配置文件
{"paths": [ "c:\\tmp", "c:/tmp/aaa" , "d:/tmp" ],"maxOutput": -1, "createdOnly" : false,"destination": "d:\\我的学习资料","toBase64": [".png", ".jpg", ".jpeg"],"toSnappy": [".txt", ".pdf"],"logFile": ".\\log\\log.txt","logLevel": "off"}
- main.cpp
#include <ctime>#include <iostream>
#include <iomanip>
#include <memory> // 智能指针 shared_ptr<>#include <libfswatch/c++/monitor_factory.hpp>
#include <CLI/CLI.hpp> #include <nlohmann/json.hpp>#include "myiconv.hpp"using json = nlohmann::json;namespace Watch::settings
{
//---------------------------------------------- // 日志级别(暂使用手工定义,007杰讲改用三方库中的定义)
enum class LogLevel
{// 跟踪、调试、信息、警告、错误 、危急、关闭trace, debug, info, warn, err, critical, off
};// 让枚举 LogLevel 支持与JSON双向转换
NLOHMANN_JSON_SERIALIZE_ENUM(LogLevel,
{{LogLevel::trace, "trace"},{LogLevel::debug, "debug"},{LogLevel::info, "info"},{LogLevel::warn, "warn"},{LogLevel::err, "err"},{LogLevel::critical, "critical"},{LogLevel::off, "off"}
})// 配置数据的结构体
struct Config
{std::vector<std::string> paths;int maxOutput = -1;bool createdOnly = false;std::string destination; std::vector<std::string> toBase64;std::vector<std::string> toSnappy;std::string logFile = "./log.txt";LogLevel logLevel = LogLevel::off;
};NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Config, paths, maxOutput, createdOnly, destination, toBase64, toSnappy, logFile, logLevel)std::string getLogLevelName(LogLevel ll)
{json j = ll;return j.get<std::string>();
}std::map<std::string, LogLevel> logLevelNameMap
{{getLogLevelName(LogLevel::trace), LogLevel::trace},#define llNameItem(ll) {getLogLevelName(LogLevel::ll), LogLevel::ll}llNameItem(debug),llNameItem(info),llNameItem(warn),llNameItem(err),llNameItem(critical),llNameItem(off)#undef llNameItem
};// 配置数据“格式器”
class MyCLIConfigAdaptor : public CLI::Config
{
public:// 如何从 JSON 数据读出 各个配置项std::vector<CLI::ConfigItem> from_config (std::istream &input) const override;// 如何从app,生成配置文件内容(字符串)std::string to_config (CLI::App const* app, bool default_also, bool write_description, std::string prefix) const override{ return ""; }
};std::vector<CLI::ConfigItem> MyCLIConfigAdaptor::from_config (std::istream &input) const
{try{json j = json::parse(input, nullptr, true /*允许异常*/, true /*允许注释*/);auto cfg = j.get<settings::Config>();auto items = std::vector<CLI::ConfigItem>{{{}, "paths", cfg.paths },{{}, "max-ouput", { std::to_string(cfg.maxOutput) }}, // 视频中误为 "max-count"{{}, "created-only", { cfg.createdOnly? "true" : "false"} },{{}, "destination", { cfg.destination }},{{}, "to-base64", cfg.toBase64},{{}, "to-snappy", cfg.toSnappy},{{}, "log-file", {cfg.logFile}},{{}, "log-level", {std::to_string(static_cast<int>(cfg.logLevel))}}};return items;}catch(json::exception const& e){std::cerr << "JSON 配置数据有误。" << e.what() << std::endl;}catch(std::exception const& e){std::cerr << "读取并转换配置数据发生异常。" << e.what() << std::endl;}return {};
}//----------------------------------------------
} // namespace Watch::settingsWatch::settings::Config theConfig; // 全局唯一的配置// 返回值:必须是 void,入参必须是 std::vector<fsw::event> const & 和 void *
void on_file_changed(std::vector<fsw::event> const & events, void *)
{/* 略,保持原有实现不变;本课,配置数据尚未发挥作用 */
}int main(int argc, char** argv) // 主函数
{// 一、定义一个CLI::App 的变量CLI::App app("HelloFSWatch");// 1.1 指定(默认的)配置文件app.set_config("--config", "./myConfig.json", "指定配置文件");// 1.2 创建并指定定制的配置数据格式解析器app.config_formatter(std::make_shared<Watch::settings::MyCLIConfigAdaptor>());// 二、添加命令行参数try{app.add_option("paths", theConfig.paths, "待监控的文件夹路径(可含多个)")->required();app.add_option("--max-output,-m", theConfig.maxOutput, "启动后输出事件个数")->default_val(-1);app.add_flag("-c,--created-only", theConfig.createdOnly, "只关注新建信息");app.add_option("--destination,-d", theConfig.destination, "输出文件路径")->required();app.add_option("--to-base64", theConfig.toBase64,"需要转成base64的文件的扩展名(数组)");app.add_option("--to-snappy", theConfig.toSnappy, "需要转成snappy的文件的扩展名(数组)");app.add_option("--log-file", theConfig.logFile, "日志文件路径")->default_val("./log.txt"); app.add_option("--log-level", theConfig.logLevel, "可输出的最小日志级别")->default_val(Watch::settings::LogLevel::off)->transform(CLI::CheckedTransformer(Watch::settings::logLevelNameMap));// 三、开始解析命令行app.parse(argc, argv);}catch(std::exception const& e){std::cerr << e.what() << std::endl;return -1;}// 显示当前生效的配置数据json j = theConfig;std::cout << "\n当前发挥作用的配置是:\n" << j.dump(2) << std::endl;auto *monitor = fsw::monitor_factory::create_monitor(system_default_monitor_type,theConfig.paths,on_file_changed);// 启动监控monitor->start(); // 进入死循环
}
相关文章:

007-nlohmann/json 项目应用-C++开源库108杰
本课为 fswatch(第一“杰”)的示例项目加上对配置文件读取的支持,同时借助 第三“杰” CLI11 的支持,完美实现命令行参数与配置文件的逻辑统一。 012-nlohmann/json-4-项目应用 项目基于原有的 CMake 项目 HelloFSWatch 修改。 C…...

移动端测试岗位高频面试题及解析
文章目录 一、基础概念二、自动化测试三、性能测试四、专项测试五、安全与稳定性六、高级场景七、实战难题八、其他面题 一、基础概念 移动端测试与Web测试的核心区别? 解析:网络波动(弱网测试)、设备碎片化(机型适配&…...
gvim比较两个文件不同并合并差异
使用 gvim 比较两个文件的不同: 方式一,使用 gvim 同时打开两个待比较的文件。 比较通用方式是采用 gvim -d 选项,具体命令,如下: gvim -d <file1> <file2>方式二,先用 gvim 打开一个文件&am…...
App使用webview套壳引入h5(二)—— app内访问h5,顶部被手机顶部菜单遮挡问题,保留顶部安全距离
引入webview的页面添加safeAreaInsets,对weview的webviewStyles做处理 在myApp中改造 entry.vue代码如下 template><view class"entry-page" :style"{ paddingTop: safeAreaInsets.top px }"><web-view :webview-styles"we…...

Git GitHub Gitee
一、Git 是一个免费、开源的分布式版本控制系统。 版本控制:一种记录文件内容变化,以便将来查阅特定版本修订情况的系统。它最重要的就是可以记录文件修改历史记录,从而让用户可以看历史版本,方便版本切换。 1.和集中式版本控制…...
《深度体验 Egg.js:打造企业级 Node.js 应用的全景指南》
🚀 核心亮点:Koa 的二次觉醒 企业级基因:阿里多年双十一验证的框架稳定性插件化架构:config.plugins 实现功能模块即插即用渐进式演进:从 50 行代码到 5 万行代码的无缝扩容能力 🔧 实战配置解析ÿ…...
蓝桥杯2118 排列字母
问题描述 小蓝要把一个字符串中的字母按其在字母表中的顺序排列。 例如,LANQIAO 排列后为 AAILNOQ。 又如,GOODGOODSTUDYDAYDAYUP 排列后为 AADDDDDGGOOOOPSTUUYYY。 请问对于以下字符串,排列之后字符串是什么? WHERETHEREIS…...
Python应用break初解
大家好!作为 Python 初学者,控制循环的执行是编程中的基础技能之一。在本文中,我们将深入探讨break语句的用途和用法,帮助您更好地理解和掌握这一强大的工具。 定义: break是 Python 中的一个保留关键字,用于在循环中提前终止循环…...

PLSQLDeveloper配置OracleInstantClient连接Oracle数据库
PL/SQLDeveloper配置Oracle Instant Client连接Oracle数据库 文章目录 PL/SQLDeveloper配置Oracle Instant Client连接Oracle数据库 1. Oracle Instant Client下载与配置1. Oracle Instant Client下载2. Oracle Instant Client解压配置1. 解压2. 配置 2. PL/SQL Developer下载、…...
高股息打底+政策催化增强+永续经营兜底
通过分析农业银行(政策红利高股息)与长江电力(垄断资源现金流堡垒)的共性,提炼出以下策略框架: 1. 核心筛选标准 • 高股息防御性:股息率>3%,分红率稳定(40%…...
双电机差速控制的MATLAB Simulink仿真方案,使用PWM和PID调节实现360°转向与速度控制_可复现,有问题请联系博主
以下是一个双电机差速控制的MATLAB Simulink仿真方案,使用PWM和PID调节实现360转向与速度控制。方案包含系统建模、控制策略和仿真实现。 系统模型 差速运动学模型: 线速度 ( v = \frac{v_r + v_l}{2} )角速度 ( \omega = \frac{v_r - v_l}{d} )其中 ( v_r, v_l ) 为右/左轮线…...

【Oracle】触发器
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 触发器基础概述1.1 触发器的概念与特点1.2 触发器的分类1.3 触发器的执行顺序 2. DML触发器2.1 基础DML触发器2.1.1 INSERT触发器2.1.2 UPDATE触发器2.1.3 DELETE触发器 2.2 高级DML触发器2.2.1 复合触发器2…...

基于深度学习的无人机轨迹预测
完整代码见文末 随着无人机技术的不断发展,无人机在农业、物流、监控等领域的应用日益广泛。精准的轨迹预测不仅能够提高无人机飞行的效率和安全性,还能在应对复杂环境下的突发状况时做出迅速反应。因此,基于深度学习的无人机轨迹预测已成为…...

git连接本地仓库以及gitee
参考:gitee创建新仓库并上传代码_gitee新建仓库导入代码-CSDN博客 git初始化以及添加git分支 在idea查看master主分支 报错 原因gitee推送更新失败问题记录:remote: error: hook declined to update refs/heads/master-CSDN博客 取消邮箱暴露...
使用Python和OpenCV实现图像识别与目标检测
在计算机视觉领域,图像识别和目标检测是两个非常重要的任务。图像识别是指识别图像中的内容,例如判断一张图片中是否包含某个特定物体;目标检测则是在图像中定位并识别多个物体的位置和类别。OpenCV是一个功能强大的开源计算机视觉库…...

麒麟v10系统的docker重大问题解决-不支持容器名称解析
今天给客户在麒麟v10Kylin-Server-V10-SP1下安装nextcloudonlyoffice的时候出现无法连接onlyoffice的问题,经过分析找到了是docker版本过低的原因,现在把解决思路和步骤分享给大家。 一、问题 用一键安装工具,给客户装好了系统,Nextcloud可以正常访问 但是访问nextcloud中的o…...

基于5G下行信号的模糊函数分析matlab仿真,对比速度模糊函数和距离模糊函数
目录 1.引言 2.算法仿真效果演示 3.数据集格式或算法参数简介 4.MATLAB部分程序 5.算法涉及理论知识概要 6.参考文献 7.完整算法代码文件获得 1.引言 模糊函数(Ambiguity Function, AF)是信号处理领域用于分析信号时频分辨能力的核心工具…...
Selenium自动下载浏览器驱动
为什么需要自动下载浏览器驱动? 血泪场景重现 新人入职第一天: 花3小时配置Chrome/Firefox驱动版本不匹配导致SessionNotCreatedException 浏览器自动更新后: 所有测试脚本突然崩溃手动查找驱动耗时长 终极解决方案:自动下载驱…...
数据库优化实战分享:高频场景下的性能调优技巧与案例解析
在实际开发与生产运维中,数据库的性能瓶颈往往是影响系统响应速度和用户体验的关键因素。尤其是在高并发访问、海量数据处理、复杂查询逻辑等高频场景下,数据库优化不仅仅是“锦上添花”,更是“雪中送炭”。本篇博文将结合实际项目经验&#…...

Redis 过期了解
Redis 版本:5.0 : 一:过期监听: Spring Data Redis 封装了 Redis 的 Pub/Sub 功能,提供了对 key 过期事件的监听支持。 1. 核心类:KeyExpirationEventMessageListener 这个抽象类是 Spring 提供的&#x…...
微信小程序前端面经
一、技术栈与编码能力(10min) 1. Vue 3 & Composition API Q1:请解释一下 ref 和 reactive 的区别?你在项目中是如何使用的? 答:ref是包装一个原始值或对象,通过.value访问,r…...
android 之 Tombstone
Android 系统中的 Tombstone 是记录 Native 层崩溃信息的关键日志文件,当应用或系统服务因严重错误(如内存访问异常、空指针解引用等)崩溃时自动生成。以下是其核心机制与分析方法详解: 一、Tombstone 的生成机制 触发条件 当 Na…...
六级作文模板笔记
旧模板 Today there is a growing awareness that mental well-being needs to be given as much attention as physical health. In the contemporary world where change is constant and knowledge is ever-expanding, mental well-being has become increasingly importan…...

JAVA理论-JAVA基础知识
1.Java 基础 知识 1.1 面向对象的特征(了解) 面向对象的特征:封装、继承、多态、抽象 封装:就是把对象的属性和行为(数据)结合为一个独立的整体,并尽量隐藏对象的内部细节,公开我希…...

免费无限使用GPT Plus、Claude Pro、Grok Super、Deepseek满血版
渗透智能-ShirtAI,可以免费无限使用GPT Plus、Claude Pro、Grok Super、Deepseek满血版、除此之外还能免费使用AI搜索、Gemini AI、AI照片修复、AI橡皮擦、AI去背景、AI智能抠图、AI证件照、OCR识别、在线思维导图、在线绘图工具、PDF工具箱、PDF翻译。 传送入口&a…...

SoloSpeech - 高质量语音处理模型,一键提取指定说话人音频并提升提取音频清晰度和质量 本地一键整合包下载
视频教程: 一个强大的语音分离和降噪软件 SoloSpeech 是由约翰霍普金斯大学、香港中文大学、南洋理工大学、清华大学及布拉格理工大学等多所高校共同主导开源的一个创新的语音处理项目,旨在解决在多人同时说话的环境中,准确提取并清晰呈现特定…...

深入解析 Java ClassLoader:揭开 JVM 动态加载的神秘面纱
大家好,这里是架构资源栈!点击上方关注,添加“星标”,一起学习大厂前沿架构! Java 之所以能实现“一次编写,到处运行”,很大程度得益于其虚拟机(JVM)强大的跨平台能力。…...

CICD实战(一) -----Jenkins的下载与安装
服务器IPJenkins192.168.242.153gitlab192.168.242.154 1、安装工具(可选,如果有就不需要安装) sudo yum install wget net-tools 2、关闭防火墙 #关闭防火墙(如果是云服务器部署,去安全组放通对应的端口即可) systemctl stop firewalld …...
【.net core】.KMZ文件解压为.KML文件并解析为GEOJSON坐标数据集。附KML处理多线(LineString)闭环问题
通过使用ZipFile解压KMZ文件,获取其中的KML文件,并解析KML文件,输出解析后的坐标数据集。 KML文件:地理信息的标准格式 解析后的坐标数据集输出格式(GEOJSON坐标数据集):[[[经度,纬度],[经度,纬度]]] 解…...
Python打卡训练营day46——2025.06.06
知识点回顾: 不同CNN层的特征图:不同通道的特征图什么是注意力:注意力家族,类似于动物园,都是不同的模块,好不好试了才知道。通道注意力:模型的定义和插入的位置通道注意力后的特征图和热力图 …...