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实例。

四、实例运行效果图。

相关推荐
是店小二呀几秒前
【Linux】Linux开发利器:make与Makefile自动化构建详解
linux·运维·自动化
baihb10241 小时前
Jenkins 构建流水线
运维·jenkins
BUG 4041 小时前
LINUX--shell
linux·运维·服务器
菜鸟小白:长岛icetea1 小时前
Linux零基础速成篇一(理论+实操)
linux·运维·服务器
深海的鲸同学 luvi1 小时前
【HarmonyOS NEXT】hdc环境变量配置
linux·windows·harmonyos
dowhileprogramming2 小时前
Python 中的迭代器
linux·数据库·python
过过过呀Glik2 小时前
在 Ubuntu 服务器上添加和删除用户
linux·服务器·ubuntu
Tesseract_95274 小时前
ioctl回顾
linux
Java小白中的菜鸟4 小时前
centos7的磁盘扩容
linux·运维·服务器
黑客老陈4 小时前
面试经验分享 | 北京渗透测试岗位
运维·服务器·经验分享·安全·web安全·面试·职场和发展