2024-07-24 Linux C語言使用inotify进行文件变化检测

一、在Linux中,用C语言检测文件内容变化的方法有几种,最常用的包括以下几种:

  1. 轮询(Polling):周期性地读取文件并检查内容是否变化。
  2. inotify :使用Linux内核提供的inotify接口,这是一个高效且常用的方法。

二、使用inotify进行文件变化检测

inotify是Linux内核提供的一个机制,用于监控文件系统事件。以下是一个使用inotify接口来检测文件内容变化的示例。

复制代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/inotify.h>
#include <unistd.h>
#include <string.h>

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


#define MAX_LINE_LENGTH 1024

//#define FILE_PATH_NAME "/sys/class/android_usb/android0/state"
#define FILE_PATH_NAME "/data/state"


void read_first_line(const char *filename, char *line, size_t max_length) {
    FILE *file = fopen(filename, "r");
    if (file == NULL) {
        perror("fopen");
        exit(EXIT_FAILURE);
    }

    if (fgets(line, max_length, file) == NULL) {
        if (feof(file)) {
            printf("The file is empty.\n");
        } else {
            perror("fgets");
        }
        //fclose(file);
        //exit(EXIT_FAILURE);
    }

    fclose(file);
}

int main() {
    int length, i = 0;
    int fd;
    int wd;
    char buffer[EVENT_BUF_LEN];
    char line[MAX_LINE_LENGTH];
	
    // 创建inotify实例
    fd = inotify_init();
    if (fd < 0) {
        perror("inotify_init");
    }

    // 添加监控的文件
    wd = inotify_add_watch(fd, FILE_PATH_NAME, IN_MODIFY);
    printf("Listen: %s \n", FILE_PATH_NAME);
	
    while (1) {
        // 读取事件
		printf("read...................\n");
        length = read(fd, buffer, EVENT_BUF_LEN);
        if (length < 0) {
            perror("read");
        }
        printf("read end length=%d...................\n",length);
       
        i = 0;
        while (i < length) {
            struct inotify_event *event = (struct inotify_event *) &buffer[i];
			printf("event->len=%d,EVENT_SIZE=%d,IN_MODIFY=%d\n" ,event->len,EVENT_SIZE,IN_MODIFY);
            if (event->mask & IN_MODIFY) {
                printf("The file was modified.\n");
			
            memset(line,0,MAX_LINE_LENGTH);			
			read_first_line(FILE_PATH_NAME, line, MAX_LINE_LENGTH);
			
			printf("The first line is: %s \n", line);
			printf("strlen(DISCONNECTED)=%d\n",strlen("DISCONNECTED"));
			if (strncmp(line, "DISCONNECTED",strlen("DISCONNECTED")) == 0) {
               printf("usb device is disconnected!\n");
            } 
	
            }
            i += EVENT_SIZE + event->len;
        }
    }

    // 移除监控和关闭inotify实例
    inotify_rm_watch(fd, wd);
    close(fd);

    return 0;
}

三、代码解释

  1. 包含头文件 :包含了必要的头文件stdio.hstdlib.hsys/inotify.hunistd.h
  2. 定义常量
    • EVENT_SIZE:单个inotify_event结构的大小。
    • EVENT_BUF_LEN:缓冲区的大小,用于存储读取到的事件。
  3. 初始化inotify实例
    • 使用inotify_init创建inotify实例。如果创建失败,打印错误信息。
  4. 添加监控的文件
    • 使用inotify_add_watch添加监控文件。这里监控文件的路径是/path/to/your/file.txt,并且监控文件的修改事件(IN_MODIFY)。
  5. 读取事件并处理
    • 使用read函数读取事件信息。如果读取失败,打印错误信息。
    • 遍历读取到的事件,检查是否包含IN_MODIFY标志。如果包含,则表示文件被修改,打印相关信息。
  6. 清理
    • 使用inotify_rm_watch移除监控。
    • 关闭inotify实例。

四、实例运行效果图。

相关推荐
改一下配置文件33 分钟前
Ubuntu24.04安装NVIDIA驱动完整指南(含Secure Boot解决方案)
linux
碳基沙盒1 小时前
OpenClaw 多 Agent 配置实战指南
运维
深紫色的三北六号10 小时前
Linux 服务器磁盘扩容与目录迁移:rsync + bind mount 实现服务无感迁移(无需修改配置)
linux·扩容·服务迁移
SudosuBash14 小时前
[CS:APP 3e] 关于对 第 12 章 读/写者的一点思考和题解 (作业 12.19,12.20,12.21)
linux·并发·操作系统(os)
哈基咪怎么可能是AI1 天前
为什么我就想要「线性历史 + Signed Commits」GitHub 却把我当猴耍 🤬🎙️
linux·github
十日十行2 天前
Linux和window共享文件夹
linux
Sinclair2 天前
简单几步,安卓手机秒变服务器,安装 CMS 程序
android·服务器
木心月转码ing2 天前
WSL+Cpp开发环境配置
linux
Rockbean3 天前
用40行代码搭建自己的无服务器OCR
服务器·python·deepseek
蝎子莱莱爱打怪3 天前
Centos7中一键安装K8s集群以及Rancher安装记录
运维·后端·kubernetes