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);
入参:

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

返回一个非负整数值作为监视描述符,用于唯一标识监视对象。
返回值为负数表示添加监视失败,错误码可通过errno获取。
2.3 inotify_rm_watch函数
从inotify实例中移除监控的文件或目录。

int inotify_rm_watch(int fd, int wd);
入参:

fd:inotify实例的文件描述符。
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的定义、编程步骤以及常用接口,并编写程序进行测试
                        
原文链接:https://blog.csdn.net/cesheng3410/article/details/136649768

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值