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

四、实例运行效果图。

相关推荐
wanhengidc几秒前
云手机公认的优势有什么
运维·服务器·游戏·智能手机·玩游戏
一匹电信狗14 分钟前
【C++】C++风格的类型转换
服务器·开发语言·c++·leetcode·小程序·stl·visual studio
赖small强16 分钟前
Linux 页缓存(Page Cache)与回写(Writeback)机制详解
linux·页缓存(page cache)·回写(writeback)·脏页
中科米堆19 分钟前
中科米堆CASAIM自动化三维测量实现注塑模具快速尺寸测量
运维·人工智能·自动化
蓝冰印28 分钟前
HarmonyOS Next 快速参考手册
linux·ubuntu·harmonyos
---学无止境---37 分钟前
Linux中在字符串中查找指定字符的第一次出现位置的汇编实现
linux
老龄程序员44 分钟前
基于OpenIddict6.4.0搭建授权认证服务
运维·服务器·identityserver
tianyuanwo1 小时前
虚拟机监控全攻略:从基础到云原生实战
linux·云原生·虚机监控
别或许1 小时前
在centos系统下,安装MYSQL
linux·mysql·centos
丁丁丁梦涛1 小时前
CentOS修改MySQL数据目录后重启失败的问题及解决方案
linux·mysql·centos