Linux应用 inotify监控文件变化

1、前言

inotify是Linux内核提供的一种文件系统监控机制,可以用来监视文件系统的变化,如文件创建、删除、修改、移动等。通过inotify,用户空间程序可以实时获取文件系统的变化事件,并做出相应的处理。

主要特点:

  • 实时性:能够实时监控文件系统的变化。
  • 高效性:采用事件驱动机制,不需要轮询文件系统。
  • 灵活性:可以监控文件或目录的变化,支持递归监控

编程步骤:

  • 调用inotify_init函数初始化一个inotify实例,获取一个inotify文件描述符。
  • 使用inotify_add_watch函数向inotify实例中添加要监控的文件或目录。
  • 调用read函数读取inotify实例中发生的事件。
  • 根据事件类型做出相应的处理。

2、编程接口

2.1 inotify_init函数

初始化一个inotify实例,并返回一个inotify文件描述符。

int inotify_init(void);

返回值:

  • 成功:返回一个新的inotify实例的文件描述符。
  • 失败:返回-1,并设置errno以指示错误。

2.2 inotify_add_watch函数

用于向inotify实例添加一个监视对象,并指定需要监视的事件类型。

int inotify_add_watch(int fd, const char *pathname, uint32_t mask);

入参:

  • fdinotify实例的文件描述符。
  • pathname:要监视的文件或目录的路径。
  • mask:事件类型的掩码,可以使用OR运算符组合多个事件类型。

返回值:

  • 返回一个非负整数值作为监视描述符,用于唯一标识监视对象。
  • 返回值为负数表示添加监视失败,错误码可通过errno获取。

2.3 inotify_rm_watch函数

从inotify实例中移除监控的文件或目录。

int inotify_rm_watch(int fd, int wd);

入参:

  • fdinotify实例的文件描述符。
  • wd:要移除的监视描述符,即监视对象的标识符。

返回值:

  • 返回0表示成功移除监视对象。
  • 返回值为负数表示移除失败,错误码可通过errno获取。

2.4 struct inotify_event结构

通过read函数读取结果,结果的组织形式为struct inotify_event结构体:

struct inotify_event {
    int      wd;       /* Watch descriptor */
    uint32_t mask;     /* Mask of events */
    uint32_t cookie;   /* Unique cookie associating related events (for rename(2)) */
    uint32_t len;      /* Size of 'name' field */
    char     name[];   /* Optional null-terminated name */
};
  • int wd:监视描述符,表示事件所属的监视对象。
  • uint32_t mask:事件标志掩码,表示事件类型的位掩码,可以包括多个事件类型。
  • uint32_t cookie:关联事件的唯一标识符,用于关联相关的事件,比如重命名操作。
  • uint32_t len:文件名长度,表示name字段的长度。
  • char name[]:可选的文件名字段,存储与事件相关的文件名。

mask字段的事件类型:

  • IN_ACCESS:文件被访问。
  • IN_MODIFY:文件被修改。
  • IN_ATTRIB:文件属性被修改。
  • IN_CLOSE_WRITE:文件被关闭,写入操作完成。
  • IN_CLOSE_NOWRITE:文件被关闭,没有写入操作。
  • IN_OPEN:文件被打开。
  • IN_MOVED_FROM:文件被移动(从监视目录移出)。
  • IN_MOVED_TO:文件被移动(移入监视目录)。
  • IN_CREATE:文件或目录被创建。
  • IN_DELETE:文件或目录被删除。
  • IN_DELETE_SELF:监视的文件或目录被删除。
  • IN_MOVE_SELF:监视的文件或目录被移动。
  • IN_ISDIR:事件涉及的是目录而不是文件。
  • IN_UNMOUNT:监视的文件系统被卸载。
  • IN_Q_OVERFLOW:事件队列溢出。
  • IN_IGNORED:监视对象被移除或删除。
  • IN_ONLYDIR:只监视目录,不监视文件。
  • IN_DONT_FOLLOW:不要跟踪符号链接的目标。
  • IN_EXCL_UNLINK:监视对象必须是存在的。
  • IN_MASK_ADD:将新事件添加到现有事件掩码。
  • IN_ONESHOT:只监视一个事件,之后自动移除监视。
  • IN_CLOSE:文件被关闭(等同于IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)。
  • IN_MOVE:文件被移动(等同于IN_MOVED_FROM | IN_MOVED_TO)。

3、编程测试

编写程序监控当前文件夹下文件的添加和删除操作,测试代码如下:

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

#define EVENT_SIZE      (sizeof(struct inotify_event))
#define BUF_LEN         (1024 * (EVENT_SIZE + 16))
#define MONITOR_PATH    "./"

int main() 
{
    int fd, wd;
    char buffer[BUF_LEN];

    fd = inotify_init();
    if (fd < 0) 
    {
        perror("inotify_init");
        exit(EXIT_FAILURE);
    }

    wd = inotify_add_watch(fd, MONITOR_PATH, IN_ALL_EVENTS);
    if (wd < 0) 
    {
        perror("inotify_add_watch");
        exit(EXIT_FAILURE);
    }

    printf("Monitoring directory %s ...\n", MONITOR_PATH);

    while (1) 
    {
        int length = read(fd, buffer, BUF_LEN);
        if (length < 0) 
        {
            perror("read");
            exit(EXIT_FAILURE);
        }

        int i = 0;
        while (i < length) 
        {
            struct inotify_event *event = (struct inotify_event *)&buffer[i];
            if (event->mask & IN_CREATE) 
            {
                printf("File %s created\n", event->name);
            } 
            else if (event->mask & IN_DELETE) 
            {
                printf("File %s deleted\n", event->name);
            }
            i += EVENT_SIZE + event->len;
        }
    }

    close(fd);
    return 0;
}

测试结果如下,程序可以捕获到当前文件夹下文件的创建和删除信息:

4、总结

本文讲述了inotify的定义、编程步骤以及常用接口,并编写程序进行测试。

  • 30
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值