inotify是2.6.13内核引入的,用来替换dnotify的,实现了一套文件系统监控机制。
Inotify 可以监视的文件系统事件包括:
- IN_ACCESS,即文件被访问
- IN_MODIFY,文件被 write
- IN_ATTRIB,文件属性被修改,如 chmod、chown、touch 等
- IN_CLOSE_WRITE,可写文件被 close
- IN_CLOSE_NOWRITE,不可写文件被 close
- IN_OPEN,文件被 open
- IN_MOVED_FROM,文件被移走,如 mv
- IN_MOVED_TO,文件被移来,如 mv、cp
- IN_CREATE,创建新文件
- IN_DELETE,文件被删除,如 rm
- IN_DELETE_SELF,自删除,即一个可执行文件在执行时删除自己
- IN_MOVE_SELF,自移动,即一个可执行文件在执行时移动自己
- IN_UNMOUNT,宿主文件系统被 umount
- IN_CLOSE,文件被关闭,等同于(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
- IN_MOVE,文件被移动,等同于(IN_MOVED_FROM | IN_MOVED_TO)
inotifytools_sprintf
%w
- This will be replaced with the name of the Watched file on which an event occurred. %f
- When an event occurs within a directory, this
will be replaced with the name of the File which caused the event to
occur. Otherwise, this will be replaced with an empty string. %e
- Replaced with the Event(s) which occurred, comma-separated. %Xe
- Replaced with the Event(s) which occurred, separated by whichever character is in the place of `X'. %T
- Replaced by the current Time in the format specified by the string previously passed to , or replaced with an empty string if that function has never been called.
%w,将会被当事件发生时检测文件的名字所替换
%f,将会被当一个事件在一个目录下发生时,导致事件发生的文件的名字所替换
%e,将会被发生的事件,以逗号作为间隔所替换
%Xe,将会被发生的事件,以"X"表示的符号作为间隔所替换
%T,将会被之前设置的时间格式所替换。
NOTES:这里需要注意%w和%f。
%w,是在检测域中检测的文件,也就是调用inotifytools_watch_recursively类函数的文件(包括路径)
%f,是引发相应事件的文件(前提是在一个目录下面进行检测,如果检测对象是一个文件,那么%f一般为空)
%w和%f可以不是一个,例如,test是一个目录,我们在test下面检测MOVED_TO事件,当move一个文件a.txt到test目录中时候 ,a.txt将会触发一个MOVED_TO事件。在这里,test是检测文件,a.txt是引发事件的文件。
如
果调用inotifytools_watch_file的话,使用%f实际上是无效的,因为%f仅用于事件作用于一个目录的情况,实际上也就是说
inotifytools_watch_recursively将会检测目录及其目录下面的递归子目录,但是不包括各个子目录下面的文件。
inotify_watch_file不能够从字面上进行理解,它不仅仅可以检测文件,还可以检测目录的,inotify检测的是inode,所以目录文件均可。
例如,我们要检测移动文件到相应目录下面的应用:
#include
#include
#include
#include
#define INOTIFY_PATH "./xml/"
/*
* libinotifytools example program.
* Compile with gcc -linotifytools example.c
*/
int main(int argc, char *argv[]) {
char fname[1024];
// initialize and watch the entire directory tree from the current working
// directory downwards for all events
if ( !inotifytools_initialize()
|| !inotifytools_watch_file( INOTIFY_PATH, IN_MOVED_TO ) ) {
fprintf(stderr, "%s\n", strerror( inotifytools_error() ) );
return -1;
}
//inotifytools_watch_file("./a", IN_CLOSE_WRITE);
// set time format to 24 hour time, HH:MM:SS
inotifytools_set_printf_timefmt( "%T" );
// Output all events as " "
struct inotify_event * event = inotifytools_next_event( -1 );
while ( event ) {
inotifytools_printf( event, "%T %w%f %e\n" );
memset(fname, 0, sizeof(fname));
inotifytools_sprintf(fname, event, "%w%f");
//printf("watches: %d\n", inotifytools_get_num_watches() );
printf("fname: %s\n", fname);
event = inotifytools_next_event( -1 );
}
inotifytools_cleanup();
}
这里没有必要使用inotifytools_watch_recursively。
======
递归侦测的时候,不能保证原子性(inotify不支持递归,递归是库自己添加的支持)。
"不能保证原子性"这个说法可能有些勉强,原文是这样的:
This function does not attempt to work atomically. If you use this
function to watch a directory tree and files or directories are being
created or removed within that directory tree, there are no guarantees
as to whether or not those files will be watched.
查了一下libinotifytools的源代码,在第一次调用inotifytools_watch_recursively的时候,会递归的遍历目录,依次将每一层次的目录或者是文件添加到检测范围进行检测。但是,当出现了一个创建事件或者是删除事件,不能够实时的将新建的文件添加到检测范围,将删除的文件从检测范围中去除。
======
参考:
http://www.ibm.com/developerworks/cn/linux/l-inotifynew/
http://www.ibm.com/developerworks/cn/linux/l-inotify.html
阅读(2901) | 评论(0) | 转发(1) |