最有效的方法是使用inotify,直接方式是直接使用
read()
系统调用。
使用
inotify
以下代码可能会对您有所帮助,在Debian 7.0,GCC 4.7上运行良好:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/inotify.h>
#define EVENT_SIZE ( sizeof (struct inotify_event) )
#define EVENT_BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) )
int main( )
{
int length, i = 0;
int fd;
int wd;
char buffer[EVENT_BUF_LEN];
fd = inotify_init();
if ( fd < 0 ) {
perror( "inotify_init error" );
}
wd = inotify_add_watch( fd, "/tmp/test_inotify", IN_CREATE | IN_DELETE | IN_ACCESS | IN_MODIFY | IN_OPEN );
length = read( fd, buffer, EVENT_BUF_LEN );
if ( length < 0 ) {
perror( "read" );
}
while ( i < length ) {
struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];
if( event->len == 0) {
printf(" Single file watching event happened\n");
} else if ( event->len ) {
if ( event->mask & IN_CREATE ) {
if ( event->mask & IN_ISDIR ) {
printf( "New directory %s created.\n", event->name );
} else {
printf( "New file %s created.\n", event->name );
}
} else if ( event->mask & IN_DELETE ) {
if ( event->mask & IN_ISDIR ) {
printf( "Directory %s deleted.\n", event->name );
} else {
printf( "File %s deleted.\n", event->name );
}
} else if( event->mask & IN_ACCESS ) {
if ( event->mask & IN_ISDIR ) {
printf( "Directory %s accessed.\n", event->name );
} else {
printf(" File %s accessed. \n", event->name );
}
} else if( event->mask & IN_MODIFY ) {
if ( event->mask & IN_ISDIR ) {
printf( "Directory %s modified.\n", event->name );
} else {
printf(" File %s modified. \n", event->name );
}
} else if( event->mask & IN_OPEN ) {
if ( event->mask & IN_ISDIR ) {
printf( "Directory %s opened.\n", event->name );
} else {
printf(" File %s opened. \n", event->name );
}
} else {
printf( "Directory or File is accessed by other mode\n");
}
}
i += EVENT_SIZE + event->len;
}
inotify_rm_watch( fd, wd );
close( fd );
}
当运行以上程序时,您可以通过创建名为
/tmp/test_inotify
的文件或目录来测试它。
详细解释请点击
这里。
使用read
系统调用
如果一个文件已经打开,并且已经读取到当前文件大小的末尾,则
read()
系统调用将返回
0
。如果某个写入者随后向此文件写入了
N
字节,那么
read()
将返回
min(N, buffersize)
。
因此,它适用于您的情况。以下是代码示例。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
typedef int FD ;
int main() {
FD filed = open("/tmp/test_inotify", O_RDWR );
char buf[128];
if( !filed ) {
printf("Openfile error\n");
exit(-1);
}
int nbytes;
while(1) {
nbytes = read(filed, buf, 16);
printf("read %d bytes from file.\n", nbytes);
if(nbytes > 0) {
split_buffer_by_newline(buf);
}
sleep(1);
}
return 0;
}
参考资料
while (fgets(line, sizeof(line), file) != 0) { process(line); } ...nanosleep?...; clearerr(file);
(然后它将循环执行while(1)
循环以尝试进行下一次读取)。 - Jonathan Lefflerclearerr(file);
会清除流中的EOF和错误位,以便它将尝试从文件中读取更多数据(而无需关闭、重新打开和重新定位文件中的当前位置)。 - Jonathan Leffler