如何使用c中的inotify来查看包含多个文件更改的目录

时间:2015-04-10 15:22:09

标签: c inotify

我有大约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 );
}

2 个答案:

答案 0 :(得分:0)

使用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();
}

答案 1 :(得分:0)

要监视目录以进行文件创建或删除,您可以使用标记inotify创建IN_CREATE | IN_DELETE实例和监视器。要监视文件或目录,首先要使用inotify创建inotify_init实例,该实例将返回文件描述符。然后,您可以使用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