使用inotify监视目录,通过在目录上添加监视来监视目录中创建的任何新文件
fd = inotify_init();
wd = inotify_add_watch(fd, "filename_with_path", IN_CLOSE_WRITE);
inotify_add_watch(fd, directory_name, IN_CLOSE_WRITE);
const int event_size = sizeof(struct inotify_event);
const int buf_len = 1024 * (event_size + FILENAME_MAX);
while(true) {
char buf[buf_len];
int no_of_events, count = 0;
no_of_events = read(fd, buf, buf_len);
while(count < no_of_events) {
struct inotify_event *event = (struct inotify_event *) &buf[count];
if (event->len) {
if (event->mask & IN_CLOSE_WRITE) {
if (!(event->mask & IN_ISDIR)) {
//It's here multiple times
}
}
}
count += event_size + event->len;
}
当我将文件scp到目录时,这会无限循环。这段代码有什么问题?它也显示相同的事件名称和事件掩码。所以,它表明事件是相同的,无限次。
没有中断声明。如果我找到一个事件,我只是打印它并继续等待read()上的另一个事件,这应该是一个阻塞调用。相反,它开始无限循环。这意味着,read不会阻止它,但会无限地为一个文件返回相同的值。
整个操作在单独的boost :: thread上运行。
修改
对不起。我得到的错误不是因为inotify而是因为sqlite最初很难检测到。我想我在这里跳了枪。经过进一步的调查,我发现inotify的效果非常好。但错误实际上来自sqlite命令:ATTACH
该命令不是预期的命令。它正在向文件中写入一些元数据。所以inotify会一次又一次地收到通知。由于它们发生得如此之快,它搞砸了应用程序。我最终不得不分解代码来理解原因。
谢谢大家。
答案 0 :(得分:2)
我没有看到你的代码有什么问题......我的运行基本上是一样的,它运行正常。我想知道测试是否存在问题,或者省略了部分代码。如果您不介意,让我们看看我们是否可以消除任何歧义。
你可以尝试一下吗(我知道这几乎是一样的,但只是幽默我)并让我知道确切测试的结果?
1)将以下代码放入test.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <sys/inotify.h>
int main (int argc, char *argv[])
{
char target[FILENAME_MAX];
int result;
int fd;
int wd; /* watch descriptor */
const int event_size = sizeof(struct inotify_event);
const int buf_len = 1024 * (event_size + FILENAME_MAX);
strcpy (target, ".");
fd = inotify_init();
if (fd < 0) {
printf ("Error: %s\n", strerror(errno));
return 1;
}
wd = inotify_add_watch (fd, target, IN_CLOSE_WRITE);
if (wd < 0) {
printf ("Error: %s\n", strerror(errno));
return 1;
}
while (1) {
char buff[buf_len];
int no_of_events, count = 0;
no_of_events = read (fd, buff, buf_len);
while (count < no_of_events) {
struct inotify_event *event = (struct inotify_event *)&buff[count];
if (event->len){
if (event->mask & IN_CLOSE_WRITE)
if(!(event->mask & IN_ISDIR)){
printf("%s opened for writing was closed\n", target);
fflush(stdout);
}
}
count += event_size + event->len;
}
}
return 0;
}
2)用gcc编译:
gcc test.c
3)在一个窗口中将其踢开:
./a.out
4)在同一目录的第二个窗口中试试这个:
echo "hi" > blah.txt
如果每次写入文件时都能正常显示输出,并且不像代码那样循环,请告诉我。如果是这样,那么从代码中省略一些重要内容。如果没有,那么系统就会有所不同。
很抱歉将其放在“回答”部分,但对于评论太多了。
答案 1 :(得分:-1)
我的猜测是read返回-1并且因为你没有尝试修复错误,所以在下一次read调用时会出现另一个错误,它也返回-1。