Linux下使用inotify实现对文件的监控
项目中,要实现用户通过网页设置參数,后台接收数据然后写串口。
网页写数据到本地文件,使用inotify监控文件的IN_MODIFY事件。当文件被改动,然后触发写串口事件。
第一个程序只把要监控的文件增加watch_list中,运行程序。发现select返回。只能检測到文件被改动,
可是假设同一时候监控多个文件。却不能区分是哪个文件被修改了。
/*This is the sample program to notify us for the file creation and file deletion takes place in “/tmp” directory*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <linux/inotify.h> #define FILE1 "request"
#define FILE2 "time"
#define EVENT_SIZE ( sizeof (struct inotify_event) )
#define EVENT_BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) ) int main( )
{
int length,i=0;
int fd,maxfd;
int wd1;
int wd2;
int ret;
fd_set rfds;
fd_set wfds;
struct timeval tv;
char buffer[EVENT_BUF_LEN]; /*creating the INOTIFY instance*/
fd = inotify_init(); /*checking for error*/
if ( fd < 0 )
{
perror( "inotify_init" );
exit(-1);
} /*adding the “/tmp” directory into watch list. Here, the suggestion is to validate the existence of the directory before adding into monitoring list.*/
wd1 = inotify_add_watch( fd,FILE1, IN_MODIFY);
if(wd1 < 0)
{
perror("inotify_add_watch");
exit(-1);
} wd2 = inotify_add_watch( fd,FILE2, IN_MODIFY);
if(wd2 < 0)
{
perror("inotify_add_watch");
exit(-1);
}
/*read to determine the event change happens on “/tmp” directory. Actually this read blocks until the change event occurs*/ while(1)
{
printf("begining while\n");
FD_ZERO(&rfds);
FD_SET(fd,&rfds);
maxfd = fd + 1;
tv.tv_sec = 10;
tv.tv_usec = 0; printf("waiting select ...\n");
ret = select(maxfd,&rfds,NULL,NULL,&tv);
switch(ret)
{
case -1:
fprintf(stderr,"select failed\n");
break;
case 0:
fprintf(stderr,"select timeout...\n");
continue;
default:
fprintf(stderr,"fd is readable.\n");
length = read(fd,buffer,EVENT_BUF_LEN);
printf("length=%d\n",length);
if(length < 0)
{
perror("read");
exit(-1);
}
while(i < length)
{
fprintf(stderr,"inside while ...\n");
struct inotify_event *event = (struct inotify_event*)&buffer[i];
printf("event->len = %d\n",event->len);
if(event->len)
{
if(event->mask & IN_MODIFY)
{
printf("detected file %s modified.\n",event->name);
}
}
i += EVENT_SIZE + event->len;
}
i = 0;
inotify_rm_watch(fd,wd1);
inotify_rm_watch(fd,wd2);
close(fd);
fd = inotify_init();
wd1 = inotify_add_watch( fd,FILE1, IN_MODIFY);
wd2 = inotify_add_watch( fd,FILE2, IN_MODIFY);
break;
/*
printf("detected file modified\n");
sleep(1);
inotify_rm_watch(fd,wd);
close(fd);
fd = inotify_init();
wd = inotify_add_watch( fd,TEST_FILE, IN_MODIFY);
break;
*/
}
printf("break switch\n"); }
inotify_rm_watch(fd,wd1);
inotify_rm_watch(fd,wd2);
close(fd); return 0;
}
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 */
};
wd identifies the watch for which this event occurs. It is one of the watch descriptors returned by a previous call to inotify_add_watch(2).
mask contains bits that describe the event that occurred (see below).
cookie is a unique integer that connects related events. Currently this is only used for rename events, and allows the resulting pair of IN_MOVE_FROM
and IN_MOVE_TO events to be connected by the application.
The name field is only present when an event is returned for a file inside a watched directory; it identifies the file pathname relative to the watched
directory. This pathname is null-terminated, and may include further null bytes to align subsequent reads to a suitable address boundary.
The len field counts all of the bytes in name, including the null bytes; the length of each inotify_event structure is thus sizeof(inotify_event)+len.
The behavior when the buffer given to read(2) is too small to return information about the next event depends on the kernel version: in kernels before
2.6.21, read(2) returns 0; since kernel 2.6.21, read(2) fails with the error EINVAL.
又细致阅读了man inotify,发现仅仅有把文件夹加入到watch_list,才干获得是文件夹中的哪一个文件被改动了。
/*This is the sample program to notify us for the file creation and file deletion takes place in “/tmp” directory*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <linux/inotify.h> #define MONITOR_PATH "/home/lucifer/working/2015_08_19"
#define EVENT_SIZE ( sizeof (struct inotify_event) )
#define EVENT_BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) ) int main( )
{
int length,i=0;
int fd,maxfd;
int wd1;
int ret;
fd_set rfds;
fd_set wfds;
struct timeval tv;
char buffer[EVENT_BUF_LEN]; /*creating the INOTIFY instance*/
fd = inotify_init(); /*checking for error*/
if ( fd < 0 )
{
perror( "inotify_init" );
exit(-1);
} /*adding the “/tmp” directory into watch list. Here, the suggestion is to validate the existence of the directory before adding into monitoring list.*/
wd1 = inotify_add_watch( fd,MONITOR_PATH, IN_MODIFY);
if(wd1 < 0)
{
perror("inotify_add_watch");
exit(-1);
} /*read to determine the event change happens on “/tmp” directory. Actually this read blocks until the change event occurs*/ while(1)
{
printf("begining while\n");
FD_ZERO(&rfds);
FD_SET(fd,&rfds);
maxfd = fd + 1;
tv.tv_sec = 10;
tv.tv_usec = 0; printf("waiting select ...\n");
ret = select(maxfd,&rfds,NULL,NULL,&tv);
switch(ret)
{
case -1:
fprintf(stderr,"select failed\n");
break;
case 0:
fprintf(stderr,"select timeout...\n");
continue;
default:
fprintf(stderr,"fd is readable.\n");
length = read(fd,buffer,EVENT_BUF_LEN);
printf("length=%d\n",length);
if(length < 0)
{
perror("read");
exit(-1);
}
while(i < length)
{
fprintf(stderr,"inside while ...\n");
struct inotify_event *event = (struct inotify_event*)&buffer[i];
printf("event->len = %d\n",event->len);
if(event->len)
{
if(event->mask & IN_MODIFY)
{
printf("detected file %s modified.\n",event->name);
}
}
i += EVENT_SIZE + event->len;
}
i = 0;
inotify_rm_watch(fd,wd1);
close(fd);
fd = inotify_init();
wd1 = inotify_add_watch( fd,MONITOR_PATH, IN_MODIFY);
break;
/*
printf("detected file modified\n");
sleep(1);
inotify_rm_watch(fd,wd);
close(fd);
fd = inotify_init();
wd = inotify_add_watch( fd,TEST_FILE, IN_MODIFY);
break;
*/
}
printf("break switch\n"); }
inotify_rm_watch(fd,wd1);
close(fd); return 0;
}
caution:当检測文件的IN_MODIFY事件的时候,会发现IN_MODIFY会触发多次
以下是原因
- Q: What is the difference between IN_MODIFY and IN_CLOSE_WRITE?
The IN_MODIFY event is emitted on a file content change (e.g. via the write() syscall) while IN_CLOSE_WRITEoccurs on closing the changed file. It means each change operation causes one IN_MODIFY event (it may occurmany times during manipulations with an open
file) whereas IN_CLOSE_WRITE is emitted only once (on closingthe file).
Linux下使用inotify实现对文件的监控的更多相关文章
- linux设置rsync+inotify实时同步文件
linux设置rsync+inotify实时同步文件 应用场景: 同步接收方:test01 接收目录:/opt/software/test/a/ 同步发起方:test02 同步目录:/opt/so ...
- linux 下C语言编程库文件处理与Makefile编写
做开发快3年了,在linux下编译安装软件算是家常便饭了.就拿gcc来说,都有不下10次了,可基本每次都会碰到些奇奇怪怪的问题.看来还是像vs.codeblocks这样的ide把人弄蠢了.便下定决心一 ...
- Linux下用rm删除的文件的恢复方法
Linux下用rm删除的文件的恢复方法_Linux教程_Linux公社-Linux系统门户网站https://www.linuxidc.com/Linux/2008-08/14744.htm linu ...
- linux下查找指定后缀的文件
1.linux下查找指定后缀的文件 例如查找当前目录下的所有后缀名时.c或.h的文件 find . -type f -regex ".*\.\(c\|h\)"
- Linux下自动清除MySQL日志文件
MySQL运行过程中会生成大量的日志文件,占用不少空间,修改my.cnf文件配置bin-log过期时间,在Linux下自动清除MySQL日志文件 [mysqld] expire-logs-days= ...
- Linux下的文件结构,及对应文件夹的作用
Linux下的文件结构,及对应文件夹的作用 /bin 二进制可执行命令 /dev 设备特殊文件 /etc 系统管理和配置文件 /etc/rc.d 启动的配置文件和脚本 /home 用户主目录的基点,比 ...
- linux下添加用户并将文件夹授权给某一个用户
### linux下添加用户并将文件夹授权给某一个用户 背景:在做一个项目时,需要外包的前端人员调试测试环境的页面,但是又不能给他服务器的账号信息,就在服务器上新添加一个子账户,再给这个账户项目文件的 ...
- Linux下的命令,删除文件夹下的所有文件,而不删除文件夹本身
Linux下的命令,删除文件夹下的所有文件,而不删除文件夹本身 rm -rf *
- linux 下用find命令查找文件,rm命令删除文件
linux 下用find命令查找文件,rm命令删除文件. 删除指定目录下指定文件find 要查找的目录名 -name .svn |xargs rm -rf 删除指定名称的文件或文件夹: find -t ...
随机推荐
- 用python代码玩微信
# 安装包 pip install -U wxpy from wxpy import * import time import json bot=Bot() my_friend = bot.frien ...
- Django 动态建表
#!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Random_lee # -*- coding: utf-8 -*- from django ...
- 查看linux ubuntu版本
ubuntu版本: lsb_release -a linux版本: uname -a proc目录下记录的当前系统运行的各种数据,version记录的版本信息直接可以通过cat查看到. 使用命令:c ...
- Python+selenium(定位一组元素)
我们熟知Webdriver有8种定位元素的方法,但是当需要定位一组元素的时候,可以使用Webdriver提供的与之对应的8种用于定位一组元素的方法,分别是: find_elements_by_id() ...
- xtu summer individual 2 C - Hometask
Hometask Time Limit: 2000ms Memory Limit: 262144KB This problem will be judged on CodeForces. Origin ...
- hexo干货系列:(八)hexo文章自动隐藏侧边栏
前言 使用Jacman主题的时候发现打开具体文章后,侧边栏还是会展示,我想要的效果是自动隐藏侧边栏,并且展示目录.但是当我修改了主题配置文件里面close_aside属性为true的时候,发现侧边栏隐 ...
- css装饰文本框input
在web程序前端页面中,<input>恐怕是用的最多的html元素了,各个需要录入信息的场合都会用到它,一般都会用css来修饰一下使得它更好看. 原始的不加修饰的文本框像下面,有些单调,页 ...
- lubuntu通过Smb访问Windows共享目录
lubuntu通过Smb访问Windows共享目录 如果未安装Smb,先安装: apt-get install smbclient smbfs 安装后,查看共享主机上的共享目录: CentOS/Red ...
- 解决静态utils里面注入mapper对象
项目中需要在一个utils工具类中,调用mapper对象来进行功能实现,然而静态方法里面直接注入会报空指针的错误,网上查了一些资料得出如下解决办法 重点步骤: 1,utils类上面添加@Compone ...
- 【HDOJ5640】King's Cake(数论)
题意: 思路: #include<cstdio> #include<cstdlib> #include<iostream> #include<algorith ...