c++如何实现支持文件监控的目录实时备份系统【实战】

夜枫大大_9497

夜枫大大_9497

2026-04-09

457人浏览

原创

Linux用inotify可高效捕获目录变更,需注意递归监控、事件可靠性(IN_MOVED_TO优于IN_CREATE)、缓冲区溢出及IN_IGNORED重监听;Windows用ReadDirectoryChangesW需手动解析链表、处理重命名配对、避免静默失败;备份前须校验文件稳定性与打开权限,增量同步依赖inode/mtime等元数据持久化,冲突需人工介入,耗时操作须异步处理。

c++如何实现支持文件监控的目录实时备份系统【实战】

Linux 下用 inotify 实现目录变更捕获

inotify 是 Linux 内核提供的轻量级文件系统事件通知机制,比轮询高效得多,且能精确到 IN_CREATE、IN_MOVED_TO、IN_DELETE 等细粒度事件。直接调用 inotify_init1() 创建实例,再用 inotify_add_watch() 监控目标路径(注意:只监控单层目录,子目录需递归添加)。

常见坑:IN_MOVED_TO 和 IN_CREATE 都可能触发新文件,但前者更可靠(避免编辑器先写临时文件再 rename 的漏报);IN_IGNORED 事件说明 watch 被自动移除(比如被监控目录被 mv 或 rm),必须重新 add_watch;缓冲区大小默认是 8KB,大量并发小文件操作时容易丢事件,建议用 IN_CLOEXEC | IN_NONBLOCK 初始化,并循环读 read() 直到 EAGAIN。

示例关键片段:

int fd = inotify_init1(IN_CLOEXEC | IN_NONBLOCK);
int wd = inotify_add_watch(fd, "/path/to/monitored", IN_CREATE | IN_MOVED_TO | IN_DELETE | IN_MOVED_FROM);

Windows 下用 ReadDirectoryChangesW 替代方案

Windows 没有 inotify,得用 ReadDirectoryChangesW() + I/O Completion Port(IOCP)或重叠 I/O。它不支持递归监控,必须为每个子目录单独创建 FindFirstChangeNotification() 或调用 ReadDirectoryChangesW() 并传入 TRUE 的 bWatchSubtree 参数(注意:该参数在远程 SMB 路径上会被忽略)。

容易踩的坑:ReadDirectoryChangesW() 返回的缓冲区内容是变长结构体 FILE_NOTIFY_INFORMATION 链表,必须手动遍历(靠 NextEntryOffset 字段跳转),不能当普通数组处理;事件类型如 FILE_ACTION_ADDED、FILE_ACTION_RENAMED_NEW_NAME 需和旧名配对才能还原完整 rename 行为;调用前必须确保目录句柄以 FILE_LIST_DIRECTORY 权限打开,否则静默失败。

跨平台封装时,别硬套 inotify 的“wd”概念——Windows 没有 watch descriptor,只有单个句柄对应一个监控流。

备份动作要避开“正在写入”的文件

直接 copy() 或 std::filesystem::copy_file() 正在被写入的文件,可能导致备份损坏(尤其是数据库日志、大型视频剪辑等)。正确做法是:收到事件后,先用 stat() / GetFileAttributesEx() 检查 mtime 是否稳定(连续两次间隔 100ms 的检查结果一致),再尝试以只读+共享读方式打开文件(Linux 用 open(..., O_RDONLY | O_NOFOLLOW),Windows 用 CreateFile(..., FILE_SHARE_READ | FILE_SHARE_WRITE))。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

若打开失败(EBUSY / ERROR_SHARING_VIOLATION),说明文件正被独占写入,应跳过本次备份,等待下一次事件;对于频繁追加的日志文件,可考虑用 lseek() + read() 读取末尾固定字节数做增量快照,而非全量拷贝。

不要依赖文件扩展名判断是否可备份——.tmp 文件可能是编辑器临时写入,也可能是合法中间产物;真正可靠的依据是文件是否可被只读打开且无写锁。

增量同步与冲突处理的实际约束

实时备份不是“复制即完成”,必须维护本地状态(比如用 SQLite 存每文件的 inode + mtime + size 或 Windows 的 FILE_ID_INFO),否则无法区分“文件 A 被删后重建”和“文件 A 被修改”。SQLite 表结构建议至少含:path TEXT PRIMARY KEY, ino INTEGER, mtime INTEGER, size INTEGER, hash BLOB(小文件可存 SHA256 前 8 字节作快速比对)。

冲突场景真实存在:用户在监控目录中手动 mv a.txt b.txt,同时备份进程刚把 a.txt 同步走,此时 b.txt 是全新 inode;又或者两个进程同时写同一文件(如日志轮转脚本 vs 应用自身)。应对策略不是“智能合并”,而是记录冲突并暂停该路径同步,人工介入。日志里必须明确写出冲突路径、事件类型、当前 inode 和上次记录 inode。

最后提醒:不要在 inotify/ReadDirectoryChangesW 回调里直接做耗时备份操作(如压缩、加密、网络上传),必须扔进线程池或消息队列;否则事件积压会导致内核缓冲区溢出,永久丢失变更。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

2025.06.09

5434

18

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

2025.07.04

5611

25

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

2023.08.10

4858

6

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.26

3479

3

查看端口占用情况windows
查看端口占用情况windows

端口占用是指与端口关联的软件占用端口而使得其他应用程序无法使用这些端口,端口占用问题是计算机系统编程领域的一个常见问题,端口占用的根本原因可能是操作系统的一些错误,服务器也可能会出现端口占用问题。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.07.27

3038

6

windows照片无法显示
windows照片无法显示

当我们尝试打开一张图片时,可能会出现一个错误提示,提示说"Windows照片查看器无法显示此图片,因为计算机上的可用内存不足",本专题为大家提供windows照片无法显示相关的文章,帮助大家解决该问题。

2023.08.01

1548

3

windows查看端口被占用的情况
windows查看端口被占用的情况

windows查看端口被占用的情况的方法:1、使用Windows自带的资源监视器;2、使用命令提示符查看端口信息;3、使用任务管理器查看占用端口的进程。本专题为大家提供windows查看端口被占用的情况的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2739

5

windows无法访问共享电脑
windows无法访问共享电脑

在现代社会中,共享电脑是办公室和家庭的重要组成部分。然而,有时我们可能会遇到Windows无法访问共享电脑的问题。这个问题可能会导致数据无法共享,影响工作和生活的正常进行。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.08

3370

4

windows自动更新
windows自动更新

Windows操作系统的自动更新功能可以确保系统及时获取最新的补丁和安全更新,以提高系统的稳定性和安全性。然而,有时候我们可能希望暂时或永久地关闭Windows的自动更新功能。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.10

1737

3

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习