2

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 すると、これが無限にループします。このコードの問題は何ですか? 同じイベント名とイベント マスクも表示されます。つまり、同じ無限回のイベントであることを示しています。

break ステートメントはありません。イベントが見つかったら、それを出力して read() で別のイベントを待ち続けます。これはブロッキング コールである必要があります。代わりに、無限ループを開始します。つまり、 read はそれをブロックしませんが、1 つのファイルに対して同じ値を無限に返します。

この操作全体は、個別の boost::thread で実行されます。

編集: 申し訳ありません。私が得ていたエラーは、inotify が原因ではなく、最初は検出するのが難しい sqlite が原因でした。私はここで銃を飛ばしたと思います。さらに調査した結果、inotify が完全に機能することがわかりました。しかし、エラーは実際には sqlite コマンドから発生しました:ATTACH

そのコマンドは、想定されていたように、すぐに使用できるコマンドではありませんでした。ファイルにメタデータを書き込んでいました。そのため、inotify は何度も通知を受け取ります。それらが非常に高速に発生したため、アプリケーションが台無しになりました。その理由を理解するために、最終的にコードを分割する必要がありました。

みんな、ありがとう。

4

2 に答える 2

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) 1 つのウィンドウで開始します。

./a.out

4)同じディレクトリからの2番目のウィンドウでこれを試してください:

echo "hi" > blah.txt

ファイルが書き込まれるたびに出力を表示するために正しく機能し、コードのようにループしないかどうか教えてください。もしそうなら、あなたのコードから省略している重要なものがあります。そうでない場合は、システムにいくつかの違いがあります。

これを「回答」セクションに入れて申し訳ありませんが、コメントするには多すぎます。

于 2012-09-05T13:09:23.733 に答える
-1

私の推測では、read は -1 を返します。エラーを修正しようとしないため、次の read 呼び出しで別のエラーが発生し、これも -1 が返されます。

于 2012-09-05T17:00:39.630 に答える