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