【问题标题】:How to watch the directory with multiple files changes using inotify in c如何在c中使用inotify查看具有多个文件更改的目录
【发布时间】:2015-04-10 15:22:08
【问题描述】:

我有大约 50 个文件在修改后的某个时间间隔移动到目录“/tmp”。我正在使用 inotify 监视此目录 /tmp 中移动到此目录的这些文件,以便我可以将这些文件合并到另一个目录中的另一个文件。

但是文件移动到这个目录 ("/tmp") 的速率,inotify 无法为除一个文件之外的其他文件提供通知。

如果使用 inotify 创建了多个具有不同名称(未知名称)的文件或将其移动到目录中,如何监视目录。

我知道我可以为每个具有其名称的文件创建多个监视描述符。 但我不知道正在创建或移动到此目录的文件名。动态创建文件,因此我无法为每个文件创建监视描述符。

下面是我的代码。

如何检查在此目录中创建的多个文件 gettign 的通知。

请帮助解决问题。 非常感谢您的帮助。 谢谢

int main( int argc, char **argv )
{
    int length, i = 0;
    int fd;
    int wd;
    char buffer[BUF_LEN];

    fd = inotify_init();

    if ( fd < 0 ) {
        perror( "inotify_init" );
    }

    wd = inotify_add_watch( fd, "/tmp/", IN_MOVED_TO);


    while (1){
        struct inotify_event *event;

        length = read( fd, buffer, BUF_LEN );

        if ( length < 0 ) {
            perror( "read" );
        }

        event = ( struct inotify_event * ) &buffer[ i ];

        if ( event->len ) {
           if ( event->mask & IN_CREATE || IN_MOVED_TO) {
                printf( "The file %s was created.\n", event->name );

            }
        }
    }
    ( void ) inotify_rm_watch( fd, wd );
    ( void ) close( fd );

    exit( 0 );
}

【问题讨论】:

    标签: c inotify


    【解决方案1】:

    要监控目录的文件创建或删除,您可以创建inotify 实例并使用标志IN_CREATE | IN_DELETE 进行监控。要监视文件或目录,首先使用inotify_init 创建inotify 实例,该实例将返回一个文件描述符。然后,您可以使用inotify_add_watch 添加要监视的文件/目录,并提供适当的标志来查找所需的更改。然后,您可以简单地使用read,它将阻止直到检测到符合您标准的更改。

    一个监视目录的简单示例(作为输入作为第一个参数 [./tmp 默认])如下:

    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <fcntl.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 dir_exists (char *d);
    
    int main (int argc, char **argv)
    {
        int length, i = 0;
        int fd;
        int wd;
        char buffer[EVENT_BUF_LEN];
        char *path = argc > 1 ? argv[1] : "./tmp";
    
        /* check directory to monitor exists */
        if (!dir_exists (path)) {
            fprintf (stderr, "error: directory does not exist '%s'.\n", path);
            return 1;
        }
    
        /* create inotify instance & validate */
        if ((fd = inotify_init ()) < 0) {
            perror ("inotify_init");
        }
    
        /* add path to inotify watch list monitor for file create, delete.
           add IN_MOVED_FROM | IN_MOVED_TO or move to/from directory */
        wd = inotify_add_watch (fd, path, IN_CREATE | IN_DELETE);
    
        /* monitor path for new file creation or deletion
          (read blocks until the change event occurs) */
        if ((length = read (fd, buffer, EVENT_BUF_LEN)) < 0) {
            perror ("read");
        }
    
        /* report name of file created or deleted  */
        while (i < length) {
            struct inotify_event *event = (struct inotify_event *) &buffer[i];
            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);
                    }
                }
            }
            i += EVENT_SIZE + event->len;
        }
        /* remove monitoring of path from the watch list. */
        inotify_rm_watch (fd, wd);
    
        /* close the inotify instance */
        close (fd);
    
        return 0;
    
    }
    
    /** test that directory exists (>=1 success, 0 otherwise)
     *  NOTE: no directory is actually created. fail occurs instead.
     */
    int dir_exists (char *d)
    {
        int flags = O_DIRECTORY | O_RDONLY;
        int mode = S_IRUSR | S_IWUSR;
        int fd = open (d, flags, mode);
    
        if (fd < 0)     /* directory does not exist */
            return 0;
        else if (fd) {  /* directory exists, rtn fd */
            close (fd);
        }
    
        return fd;
    }
    

    编译

    gcc -Wall -Wextra -o bin/inotify_watch inotify_watch.c
    

    使用示例

    $ ./bin/inotify_watch &
    [1] 16916
    
    $ touch tmp/file.txt
    New file file.txt created.
    [1]+  Done                    ./bin/inotify_watch
    

    【讨论】:

      【解决方案2】:

      使用函数 FindFirstFile 和 FindNextFile。例如,显示以下代码:

      #include <windows.h>
      #include <stdio.h>
      #include <sys/stat.h>
      #include <io.h>
      /*
      HANDLE FindFirstFile
      (
          LPCTSTR lpFileName,     // какой файл ищем, можно указывать маску *, ?
          LPWIN32_FIND_DATA lpFindFileData    // указатель на структуру с информацией
      );*/
      //В случае ошибке вернет INVALID_HANDLE_VALUE. Для продолжения поиска используется функция:
      /*
      BOOL FindNextFile
      (
          HANDLE hFindFile,           // указатель на поиск 
          LPWIN32_FIND_DATA lpFindFileData    // указатель на структуру с информацией
      );*/
      
      
      //Write this any address
      #define DISK "C:\\"
      void main()
      {
      
          WIN32_FIND_DATA FindFileData;
          HANDLE hf;
          struct stat st;
      
          hf=FindFirstFile(DISK"*", &FindFileData);
      
          if (hf!=INVALID_HANDLE_VALUE)
          {
              do
              {
                  char s[MAX_PATH] = DISK;
                  int a;
      
                  strcat(s, FindFileData.cFileName);
                  stat(s, &st);
                  a = access(s, 04);
                  printf("%s\t\t%s\n", FindFileData.cFileName, st.st_mode & S_IFDIR ? "Directory" : (st.st_mode & S_IFREG ? "File" : "Other"));
              }
              while (FindNextFile(hf,&FindFileData)!=0);
              FindClose(hf);
          }
      
          getchar();
      }
      

      【讨论】:

      • 您好康斯坦丁·德多夫,感谢您的回复。但我正在linux平台上的C中寻找类似这个函数的东西。 windows 代码对我帮助不大。
      猜你喜欢
      • 1970-01-01
      • 2013-08-27
      • 1970-01-01
      • 2017-01-10
      • 2015-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多