You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C语言中监控目录或文件的重命名操作?——inotify实现及替代方案

监控文件/目录重命名:inotify的支持与替代方案

嘿,好问题!我刚好在类似的文件监控项目里折腾过inotify的重命名捕获,给你理得明明白白:

首先:inotify完全可以搞定文件/目录的重命名监控!

你之前的检索可能没挖到关键点——当文件或目录被重命名时,inotify会触发两个关联的事件:

  • IN_MOVED_FROM:对应原路径的“移出”事件,会带上原名称和一个唯一的cookie值
  • IN_MOVED_TO:对应新路径的“移入”事件,会带上新名称和同一个cookie值

通过这个cookie,你就能把两个事件关联起来,明确这是一次完整的重命名操作。甚至如果是跨目录移动文件,只要两个目录都在你的监控范围内,同样能通过cookie匹配到前后路径。

给你贴个极简的C代码示例,演示怎么捕获这些事件:

#include <stdio.h>
#include <stdlib.h>
#include <sys/inotify.h>
#include <unistd.h>
#include <signal.h>

#define BUF_SIZE 1024 * (sizeof(struct inotify_event) + 16)
int keep_running = 1;

void handle_exit(int sig) {
    keep_running = 0;
}

int main() {
    int inotify_fd, watch_fd;
    char buf[BUF_SIZE];
    ssize_t bytes_read;
    struct inotify_event *event;

    // 注册信号处理,方便优雅退出
    signal(SIGINT, handle_exit);

    // 初始化inotify实例
    inotify_fd = inotify_init();
    if (inotify_fd == -1) {
        perror("Failed to initialize inotify");
        exit(EXIT_FAILURE);
    }

    // 添加监控:当前目录,捕获移动相关事件
    watch_fd = inotify_add_watch(inotify_fd, ".", IN_MOVED_FROM | IN_MOVED_TO);
    if (watch_fd == -1) {
        perror("Failed to add watch");
        close(inotify_fd);
        exit(EXIT_FAILURE);
    }

    printf("Watching current directory for renames. Press Ctrl+C to exit.\n");

    while (keep_running) {
        bytes_read = read(inotify_fd, buf, BUF_SIZE);
        if (bytes_read == -1) {
            perror("Failed to read inotify events");
            break;
        }

        // 遍历所有返回的事件
        for (char *ptr = buf; ptr < buf + bytes_read; ptr += sizeof(struct inotify_event) + event->len) {
            event = (struct inotify_event *)ptr;

            if (event->mask & IN_MOVED_FROM) {
                printf("[RENAME START] Old name: %s | Cookie: %u\n", event->name, event->cookie);
            } else if (event->mask & IN_MOVED_TO) {
                printf("[RENAME END] New name: %s | Cookie: %u\n", event->name, event->cookie);
                // 这里可以用cookie匹配之前的IN_MOVED_FROM事件,关联完整重命名记录
            }
        }
    }

    // 清理资源
    inotify_rm_watch(inotify_fd, watch_fd);
    close(inotify_fd);
    printf("\nStopped monitoring.\n");
    return EXIT_SUCCESS;
}

注意:如果是监控单个文件,重命名后原文件的watch会失效,你需要在捕获IN_MOVED_TO事件后,重新给新路径添加watch。

要是真的不想用inotify,这些C语言方案也能行

如果因为某些限制不能用inotify(比如老内核不支持),可以考虑这些替代:

  • fanotify:Linux内核提供的更底层的文件系统监控接口,能监控整个挂载点或文件系统,捕获重命名等操作,还能获取文件inode信息。不过它需要root权限,接口比inotify复杂,适合大规模、跨目录的监控场景。
  • 定期轮询:最简单但效率最低的方式——用stat或readdir定期扫描目标目录,记录文件的inode和名称,对比前后差异来检测重命名。适合监控范围小、对实时性要求不高的场景。
  • dnotify:比较老旧的接口,基于目录文件描述符的通知,功能有限(只能监控目录,不能监控单个文件),现在基本被inotify取代,不推荐新项目使用。

总的来说,inotify是当前Linux上最适合做用户态文件监控的工具,完全能满足你重命名监控的需求,优先用它就对了。

内容的提问来源于stack exchange,提问作者Sky wifibrand

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 09:27:43