项目中,要实现用户通过网页设置參数,后台接收数据然后写串口。

网页写数据到本地文件,使用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).

引用地址:http://inotify.aiken.cz/?section=inotify&page=faq

Linux下使用inotify实现对文件的监控的更多相关文章

  1. linux设置rsync+inotify实时同步文件

    linux设置rsync+inotify实时同步文件   应用场景: 同步接收方:test01 接收目录:/opt/software/test/a/ 同步发起方:test02 同步目录:/opt/so ...

  2. linux 下C语言编程库文件处理与Makefile编写

    做开发快3年了,在linux下编译安装软件算是家常便饭了.就拿gcc来说,都有不下10次了,可基本每次都会碰到些奇奇怪怪的问题.看来还是像vs.codeblocks这样的ide把人弄蠢了.便下定决心一 ...

  3. Linux下用rm删除的文件的恢复方法

    Linux下用rm删除的文件的恢复方法_Linux教程_Linux公社-Linux系统门户网站https://www.linuxidc.com/Linux/2008-08/14744.htm linu ...

  4. linux下查找指定后缀的文件

    1.linux下查找指定后缀的文件 例如查找当前目录下的所有后缀名时.c或.h的文件 find  .  -type f -regex  ".*\.\(c\|h\)"

  5. Linux下自动清除MySQL日志文件

    MySQL运行过程中会生成大量的日志文件,占用不少空间,修改my.cnf文件配置bin-log过期时间,在Linux下自动清除MySQL日志文件 [mysqld] expire-logs-days= ...

  6. Linux下的文件结构,及对应文件夹的作用

    Linux下的文件结构,及对应文件夹的作用 /bin 二进制可执行命令 /dev 设备特殊文件 /etc 系统管理和配置文件 /etc/rc.d 启动的配置文件和脚本 /home 用户主目录的基点,比 ...

  7. linux下添加用户并将文件夹授权给某一个用户

    ### linux下添加用户并将文件夹授权给某一个用户 背景:在做一个项目时,需要外包的前端人员调试测试环境的页面,但是又不能给他服务器的账号信息,就在服务器上新添加一个子账户,再给这个账户项目文件的 ...

  8. Linux下的命令,删除文件夹下的所有文件,而不删除文件夹本身

    Linux下的命令,删除文件夹下的所有文件,而不删除文件夹本身 rm -rf *

  9. linux 下用find命令查找文件,rm命令删除文件

    linux 下用find命令查找文件,rm命令删除文件. 删除指定目录下指定文件find 要查找的目录名 -name .svn |xargs rm -rf 删除指定名称的文件或文件夹: find -t ...

随机推荐

  1. 5. 在Datadir目录外创建单独表空间

    5. 在Datadir目录外创建单独表空间 要在MySQL dadadir之外的位置创建单独表空间,请使用该子句: DATA DIRECTORY = '/path' 在目标目录中,MySQL会创建一个 ...

  2. python的2种字符串格式化输出

    字符串格式化代码(typecode) 法一: %格式使用下面的格式 %[(name)] [flags] [width][.precision] typecode (name)输出字典的value使用, ...

  3. Linux mint xfce 19 使用记录

    创建系统快照 创建系统快照是 Linux Mint 19 的重要建议,可以使用与更新管理器捆绑的 Timeshift 应用程序轻松完成创建与恢复. 这个阶段很重要,万一出现令人遗憾的事件,比如安装破坏 ...

  4. mysql 常用命令(一)

    1. 函数向日期添加指定的时间间隔 DATE_ADD(date,INTERVAL expr type)eg:DATE_ADD(CURDATE(),INTERVAL 1 MONTH) //在当前时间加一 ...

  5. 利用nginx设置浏览器协商缓存

    强缓存与协商缓存的区别 强缓存:浏览器不与服务端协商直接取浏览器缓存 协商缓存:浏览器会先向服务器确认资源的有效性后才决定是从缓存中取资源还是重新获取资源 协商缓存运作原理 现在有一个这样的业务情景: ...

  6. MySQL 慢查询优化

    为什么查询速度会慢 1.慢是指一个查询的响应时间长.一个查询的过程: 客户端发送一条查询给服务器 服务器端先检查查询缓存,如果命中了缓存,则立可返回存储在缓存中的结果.否则进入下一个阶段 服务器端进行 ...

  7. luogu4135 作诗

    看这里 #include <iostream> #include <cstring> #include <cstdio> #include <cmath> ...

  8. OO第三次作业总结(JML)

    第三单元的课题是JML, 即java建模语言.JML是一种描述接的语言.通过前置条件和后置条件,描述一个模块的行为.本单元我们扮演一个项目中的一员,完成自己的一小部分工作,最终实现整个项目.而限制我们 ...

  9. xhprof安装&&使用[转载]

    编译安装 wget http://pecl.php.net/get/xhprof-0.9.2.tgz tar zxf xhprof-0.9.2.tgz cd xhprof-0.9.2/extensio ...

  10. hdu1875kruskal简单应用。

    标记是dificulty 2,水,开始kruskal时练手题,只需开始时数据处理下,不符合要求的边不要,要理解并查集和Kruskal,就简单了,判断下是否联通图,(只需在记加入有效边时候统计连通分支数 ...