001-监控你的文件-FSWatch-C++开源库108杰

  1. fswatch 原理与应用简介
  2. fswatch 安装
  3. fswatch 实践应用
  4. 具体应用场景与细节补充

在这里插入图片描述

1. 简介

有些知识,你知道了不算厉害,但你要是不知道,就容易出乱。

很多时候,程序需要及时获取磁盘上某个文件对象(文件夹、文件)的变动信息,这时候 “绝大多数操作系统支持主动推送此类信息” 这个知识点,就很重要。

如果不知道这点,大概就只能让程序定时去检查、并维护前后两套数据,自行对比以发现是否有哪个文件对象发生了哪些变化。

fswatch 本是多数 linux 下的一个工具程序——但现已经支持跨平台。它提供动态库和配套的 C、C++头文件 (合称为 libfswatch),借助它,我们也可以在自己的程序中,直接获得监控指定文件对象变动信息。

更多关于文件变动信息监控以及 libfswatch 库的基本原理、功能以及应用场景示例,请看视频 A。

  • 视频 A : FSWatch 简介

001-监控你的文件-1原理简介-C++开源库108杰

2. 安装 fswatch

Linux 下,可以使用各自发行版自带的包管理器安装 fswatch。以 Ubuntu 为例:

sudo apt install fswatch

Windows下,因为我们使用 msys2 来安装 fswatch。进入对应环境(我们的课程使用的是 ucrt64)的终端,输入以下指令即可:

pacman -S mingw-w64-ucrt-x86_64-fswatch

msys2 本身的安装可看课程 《VSCODE 多语言开发保姆手册》)的第一节课 《MSys2 + GCC 安装与应用》。

如果你手快并且长得帅的话,最快十秒钟具体操作过程以及效果演示,见视频 B 。

002-监控你的文件-2十秒安装-C++开源库108杰

3. 上机实践

我们使用 Windows + Msys2 + VSCode + GCC + CMake 的开发环境,相关准备工作同样可观看 《VSCODE 多语言开发保姆手册》)。

  • 视频 C: 上机实践

003-监控你的文件-3使用示范-C++开源库108杰

3.1 CMakeList.txt

cmake_minimum_required(VERSION 3.15.0)
project(HelloFSWatch VERSION 0.1.0 LANGUAGES C CXX)add_executable(HelloFSWatch main.cpp)target_link_libraries(${PROJECT_NAME} PRIVATE fswatch) 
target_link_directories(${PROJECT_NAME} PRIVATE "C:/msys64/ucrt64/bin")

说明:

其中最后两行是我们添加的。

  • 第一行 target_link_libraries 用于告诉编译器,当前项目需要链接到 fswatch 这个库;
  • 第二行 target_link_directories 则告诉编译器,上哪里去找 fswatch 这个库;
  • PRIVATE 用于指示对应的设置,仅在当前目标中生效,对我们这个小项目并无影响;
  • ${PROJECT_NAME} 是 CMake 的内置变量,用于表示当前项目名称,即 HelloFSWatch (见第2行的 project 语句)

GCC 在链接某个库时,会自动为它加上 lib 前缀,以及对应的扩展名,本例为 .dll,因此,我们在 CMake 源文件中写的 fswatch,最终会组成全名 “libfswatch.dll”

3.2 main.cpp

#include <ctime>#include <iostream>
#include <iomanip>#include <libfswatch/c++/monitor_factory.hpp>// 返回值:必须是 void,入参必须是 std::vector<fsw::event> const & 和 void *
void on_file_changed(std::vector<fsw::event> const & events, void *)
{std::cout << "Files Changed:\n";for (auto const& event : events){// 输出变动的文件路径:std::cout << event.get_path() << "\n";// 输出变动的时间:std::time_t t = event.get_time();std::tm lt; // local time 本地时间结构localtime_s(&lt, &t); // C11 开始支持的线程安全的时间转换函数std::cout << std::put_time(&lt, "%Y-%m-%d %H:%M:%S") << "\n";// 输出变动的标志:std::cout << "Flags:\n";for (auto const& flag : event.get_flags()){std::cout << "\t" << fsw_get_event_flag_name(flag) << "\n";}}
}int main(int, char**) 
{std::vector<std::string> paths = {"d:\\tmp"};auto *monitor = fsw::monitor_factory::create_monitor(system_default_monitor_type,paths,on_file_changed);// 启动监控monitor->start();  // 进入死循环
}

如代码所示,使用 fswatch 实现被动式响应(那操作系统主动回调我们的函数)的文件变动监控过程,关键三步:

Step1 : 通过工厂类的静态方法 create_monitor 创建一个监控器。需指定类型(通常就是采用代码中的默认类型)、待监控的文件对象路径(默认类型下,Windows 操作系统仅支持以文件夹为单位进行测控,因此该参数只能填写文件夹),回调函数;实际还有第四个默认参数,用于向回调函数传递额外的参数,通常并不需要,因此它有默认值 nullptr;

Step2 : 准备好你的回调函数(即代码中的 on_file_changed ),注意,该函数原型须严格符合:void (std::vectorfsw::event const& , void *) ;

Step3 : 启动监控。

3.3 on_file_changed 详解

回调函数名字无所谓。第一个入参类型需为 std::vectorfsw::event const& ,这是一个常量引用,第二个入参为 void *,即前面创建监控器,所传入的第四个参数(我们使用的了函数参数默认值)。

第一个入参 events 是复数(一个容器),表明该函数被操作系统回调用时,操作系统可能想告诉我们的情况有可能是:

  • 一个文件对象的一个变动事件;
  • 一个文件对象的多个变动事件;
  • 多个文件对象的多个变动事件。

每一个 event 主要包含:变动文件路径的对象(如果变动对象是一个文件,此时Windows系统上报的也是文件名),变动时间(注意,不一定非常精确),变动标志等。

库为变动标志取了一些英文名字,常见的有:

  • NoOp : 无变动
  • PlatformSpecifc :特定平台指定
  • Created
  • Updated
  • Removed
  • OwnerModified : 对象的拥有者变化,常见于 *uix 系统;
  • AttributeModified: 对象属性发生变化
  • MovedFrom
  • MovedTo
  • ……

每个变动事件可能包含有多个变动标志。

on_file_changed 第一层循环用来遍历所有事件,输出每个对象变动路径、时间。其中用到 纯C(不要加 std::)的,C11 才支持安全的时间转换函数 localtime_s 和 C++ 输出的扩展的格式操控符:put_time() 注意操控符并不返回字符串。

有关 C++ 流与操控符(比如,如何自定义一个输入或输出流操控符),可学习 《C++“流”编程视频辅导》。

第二层循环输出当前事件的所有标志,其中用到 fsw_get_event_flag_name()以获取指定标志值对应的英文名称。

4. 补充

4.1 场景补充

许多问题,确实可以通过这个“消息队列”轻松实现,除视频中提到的给用户发送通知邮件之外,还有如下场景可考虑使用:

  • 用户上传文件内容审核:某网站系统,允许用户发表带图的文章,需要对图片或文章的文字内容做安全审核;
  • 线上系统自动源代码编译:程序员使用 git 等工具,将相关模块的源代码上传到服务器上并触发自动编译;
  • 数据采集与比对系统:为了稳定性,很多监控系统会划分成数据采集与数据比对两个独立的子进程。

4.2 细节补充

“封包” 文件:很多时候,接收方发现出现一个新增的文件,并不能直接开始读取它,因为此时发送方可能还在往该文件中写入数据。此时有两种经典解决方法。

  • 方法一:要求发送方以独占模式打开文件,对应的,接收方尝试也以独占模式打开,这样后者将失败,从而避免双方同时处理(哪怕一写一读);
  • 方法二:双方约定特定文件名称(通常是扩展名)为 “封包”文件。比如,约定 .seal为封包文件的扩展名。则当发送方先生成 a.dat 文件,再生成名为 a.dat.seal 的封包文件(通常是一个零字节文件);接收方仅在发现后者之后,才开始处理 a.dat(并在处理结束后,删除封包文件)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/19607.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习--逻辑回归

机器学习–逻辑回归 一、认知革命&#xff1a;从线性回归到逻辑回归 1.1 本质差异对比 维度线性回归逻辑回归输出类型连续值概率值 (0-1)目标函数最小二乘法极大似然估计数学表达式 y w T x b yw^Txb ywTxb p 1 1 e − ( w T x b ) p\frac{1}{1e^{-(w^Txb)}} p1e−(wTxb…

s1K 数据集:是一个用于提升语言模型推理能力的高质量数据集。包含 1,000 个问题,每个问题都配有详细的 推理路径 和 答案。

2025-02-07&#xff0c; 由斯坦福大学、华盛顿大学等研究机构创建了 s1K 数据集&#xff0c;该数据集包含 1,000 个精心挑选的问题&#xff0c;并配以推理轨迹和答案&#xff0c;为语言模型推理能力的提升提供了重要的数据基础。 一、研究背景 1. 研究背景 近年来&#xff0c;…

DockerDesktop更改默认的磁盘镜像地存储位置

DockerDesktop更改默认的磁盘镜像地存储位置 文章目录 DockerDesktop更改默认的磁盘镜像地存储位置1. 默认存储位置2. 新建一个目录3. 将磁盘镜像存储位置改为新建的目录下 1. 默认存储位置 2. 新建一个目录 如&#xff1a;D:\DiskImagelocationData 3. 将磁盘镜像存储位置改为…

ASP.NET Core SixLabors.ImageSharp 位图图像创建和下载

从 MVC 控制器内部创建位图图像并将其发送到浏览器&#xff1b;用 C# 编写并与 Linux 和 Windows 服务器兼容。 使用从 ASP.NET MVC 中的控制器下载任何文件类型File。 此示例创建一个位图 (jpeg) 并将其发送到浏览器。它需要 NuGet 包SixLabors.ImageSharp v1.0.4。 另请参…

容联云联络中心AICC:深度整合DeepSeek,业务验证结果公开

容联云重磅推出AICC3.2版本&#xff0c;实现了智能化的升级与外呼效率的突破——深度整合DeepSeek-R1大模型、预测式外呼在数据分析侧的增强、全渠道路由能力、一键多呼效率的强化。 同时&#xff0c;全面接入DeepSeek-R1的容联云 AICC3.2 &#xff0c;目前已与某知名汽车金融企…

链表和list

链表和list ‍ ​ ​ ​ ​ ​ ​ ​ ​ ​ 算法题中的经典操作&#xff1a;用空间代替时间​ ​ ​ ​ 双链表头插顺序&#xff1a; 1.先修改新结点的左右指针 2.然后修改结点y的左指针 3.最后修改哨兵位的右指针 双链表在任意位置&#xff08;p&#xff09;之后插入…

Junit——白盒测试

Java单元测试框架&#xff0c;主要用于测试Java程序中的各个单元。 1.验证代码功能是否符合预期 2.及时 发现修复 代码中的缺陷&#xff0c;提高代码质量 入门 最早学习java&#xff0c;代码对不对&#xff0c;通过main 方法运行&#xff0c;观看结果是否符合预期。 packa…

1.MySQL概述

1.1 数据模型 介绍完了Mysql数据库的安装配置之后&#xff0c;接下来我们再来聊一聊Mysql当中的数据模型。学完了这一小节之后&#xff0c;我们就能够知道在Mysql数据库当中到底是如何来存储和管理数据的。 在介绍 Mysql的数据模型之前&#xff0c;需要先了解一个概念&#x…

Deep seek学习日记1

Deepseek最强大的就是它的深度思考&#xff0c;并且展现了它的思考过程。 五种可使用Deep seek的方式&#xff08;应该不限于这五种&#xff0c;后续嵌入deepseek的应该更多&#xff0c;多了解一点因为官网容易崩~~&#xff09;&#xff1a; 1.deep seek官网 2.硅基流动silicon…

JAVA中的异常

一、简介 1.1 什么是异常 异常&#xff0c;是对程序在运行过程中遇到的种种不正常的情况的描述。异常在java中用Exception类来描述。如果程序遇到了未经处理的异常&#xff0c;将会导致程序无法编译或者无法继续运行。 1.2 异常的继承体系 在java中使用类Throwable来描述所有…

数字水印嵌入及提取系统——基于小波变换GUI

数字水印嵌入及提取系统——基于小波变换GUI 基于小波变换的数字水印系统&#xff08;Matlab代码GUI操作&#xff09; 【有简洁程序报告】【可作開题完整文档达辩PPT】 本系统主要的内容包括&#xff1a; &#xff08;1&#xff09;使用小波变换技术实现二值水印图像的加密、…

Linux_帮助指令

man 获得帮助信息 基本语法: man [命令或配置文件] 在linux下,隐藏文件是以 .开头, 选项可以组合使用, 比如 ls -al, 不如 ls -al /root help 指令 基本语法: help 命令 (功能描述: 获取shell内置命名的帮助信息) 英语不好建议百度

Day4 25/2/17 MON

【一周刷爆LeetCode&#xff0c;算法大神左神&#xff08;左程云&#xff09;耗时100天打造算法与数据结构基础到高级全家桶教程&#xff0c;直击BTAJ等一线大厂必问算法面试题真题详解&#xff08;马士兵&#xff09;】https://www.bilibili.com/video/BV13g41157hK?p4&v…

redis集群模式

1.集群模式 作用&#xff1a;解决单点故障问题 集群的模式&#xff1a;1.主从模式&#xff0c;2、哨兵模式&#xff0c;3、集群化模式 1.1主从模式 特点&#xff1a;1个主节点多个从节点&#xff0c;主节点负责读写操作&#xff0c;而从节点只能负责读操作&#xff0c;当主…

力扣 乘积最大子数组

动态规划&#xff0c;注意负负得正&#xff0c;dp交换。 题目 注意这里的dp的乘积要求最大&#xff0c;而两个很大的负数相乘也是大的&#xff0c;因此在每遍历到一个数时要存一个最大值的dp与一个最小值的dp&#xff0c;然后遍历完后再去存ans的dp。由于存在负数&#xff0c;…

【Postgresql】Windows 部署 Postgresql 数据库 (图文教程)

文章目录 准备工作Postgresql 下载Postgresql 安装初始化数据库数据库链接设置允许远程连接测试链接 更多相关内容可查看 准备工作 操作系统&#xff1a;Windows 7 或更高版本&#xff08;推荐 Windows 10 或 Windows Server 2016&#xff09;。 硬件要求&#xff1a; 至少 …

【ENSP】链路聚合的两种模式

【ENSP】链路聚合的两种模式 1、背景介绍2、链路聚合的使用场景3、配置过程1、手工模式Eth-Trunk配置2、静态LACP模式Eth-Trunk 4、总结 1、背景介绍 随着网络规模的不断扩大&#xff0c;人们对骨干链路的带宽吞吐量和可靠性提出了越来越高的要求。在传统方案中&#xff0c;为…

《深度学习》——调整学习率和保存使用最优模型

调整学习率 在使用 PyTorch 进行深度学习训练时&#xff0c;调整学习率是一个重要的技巧&#xff0c;合适的学习率调整策略可以帮助模型更好地收敛。 PyTorch 提供了多种调整学习率的方法&#xff0c;下面将详细介绍几种常见的学习率调整策略及实例代码&#xff1a; torch.opt…

SpringBoot+微信小程序+数据可视化的宠物到家喂宠服务(程序+论文+讲解+安装+调试+售后等)

感兴趣的可以先收藏起来&#xff0c;还有大家在毕设选题&#xff0c;项目以及论文编写等相关问题都可以给我留言咨询&#xff0c;我会一一回复&#xff0c;希望帮助更多的人。 系统介绍 在经济高速发展、物质生活极大丰富的当下&#xff0c;人们的精神需求愈发凸显&#xff0…

《仙台有树》追剧疑问与DeepSeek解答

本篇形式&#xff1a;直接以两段对话直接呈现&#xff0c;有删减 本篇背景&#xff1a;看过太多逻辑bug&#xff0c;有些bug无药可救直接弃剧&#xff0c;有些bug情有可原包容理解。想到最近大火的DeepSeek&#xff0c;就与时俱进&#xff0c;简单直接点吧&#xff0c;也许自己…