Linux inotify使用教程以及解析

今天在阅读 Android getevent源码的时候,看到inotify,有点不理解,记录一下。

什么是 inotify

inotify(inode notify)是 Linux 内核提供的一种用于监控文件系统变化的机制。它允许程序监控文件系统中的文件或目录的各种事件(如文件的创建、删除、修改等),以便程序可以在这些事件发生时做出响应。

使用 inotify 的基本步骤

1.创建 inotify 实例:

使用 inotify_init() 函数创建一个 inotify 实例,它返回一个文件描述符,后续操作都通过该描述符进行。

2.添加监控项:

使用 inotify_add_watch() 函数向 inotify 实例添加需要监控的文件或目录,并指定要监控的事件类型。

3.读取事件:

使用 read() 或其他机制(如 poll 或 select)来读取事件,并对事件做出相应的处理。

4.移除监控项:

使用 inotify_rm_watch() 函数从 inotify 实例中移除监控项。

5.关闭 inotify 实例:

使用 close() 关闭 inotify 文件描述符。

主要函数

1.inotify_init()

int inotify_init(void);
这个函数创建一个 inotify 实例,返回一个文件描述符。如果出错,返回 -1 并设置 errno

2.inotify_add_watch()

int inotify_add_watch(int fd, const char *pathname, uint32_t mask);
这个函数为某个文件或目录添加监控。参数 fd 是 inotify 文件描述符,pathname 是需要监控的文件或目录路径,mask 是需要监控的事件类型。返回一个监控描述符,用于标识这个监控项。如果出错,返回 -1 并设置 errno

3.inotify_rm_watch()

int inotify_rm_watch(int fd, int wd);
这个函数移除某个监控项。参数 fd 是 inotify 文件描述符,wd 是需要移除的监控描述符。返回 0 成功,出错返回 -1 并设置 errno

4.事件结构体

struct inotify_event {
    int wd;       /* Watch descriptor */
    uint32_t mask;      /* Mask of events */
    uint32_t cookie;    /* An unique cookie associating related events (for rename(2)) */
    uint32_t len;       /* Size (including nulls) of name */
    char name[]; /* Name (length specified by len) */
};

主要事件类型

  • 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:自己被移动(监控的文件或目录本身被移动)

示例代码

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

#define EVENT_SIZE (sizeof(struct inotify_event))
#define EVENT_BUF_LEN (1024 * (EVENT_SIZE + 16))

int main()
{
    // 创建 inotify 实例
    int inotify_fd = inotify_init();
    if (inotify_fd < 0)
    {
        perror("inotify_init");
        exit(EXIT_FAILURE);
    }

    // 添加监控的目录
    int watch_fd = inotify_add_watch(inotify_fd, "/home/xxx/code/linux/inotifyApi", IN_CREATE | IN_DELETE | IN_MODIFY);
    if (watch_fd == -1)
    {
        perror("inotify_add_watch");
        exit(EXIT_FAILURE);
    }

    char buffer[EVENT_BUF_LEN];

    while (1)
    {
        // 读取事件
        int length = read(inotify_fd, buffer, EVENT_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->len)
            {
                if (event->mask & IN_CREATE)
                {
                    printf("File %s was created.\n", event->name);
                }
                else if (event->mask & IN_DELETE)
                {
                    printf("File %s was deleted.\n", event->name);
                }
                else if (event->mask & IN_MODIFY)
                {
                    printf("File %s was modified.\n", event->name);
                }
            }
            i += EVENT_SIZE + event->len;
        }
    }

    // 移除监控
    inotify_rm_watch(inotify_fd, watch_fd);

    // 关闭 inotify 文件描述符
    close(inotify_fd);

    return 0;
}

运行结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是李校长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值