рекурсивно inotify, как это сделать? - PullRequest
5 голосов
/ 05 февраля 2012

Мне нужно напечатать события в папке с несколькими подпапками. как это сделать рекурсивно? Пожалуйста, напечатайте код C ++. Я застрял !! Каждый раз, когда всплывает evet, мне нужно открыть подпапку, взять файл и скопировать его в другой каталог. Я не хочу перечислять все подпапки каждые 2 секунды и находить файлы, если они есть. Не эффективно. Мне нужно использовать папку монитора. Пожалуйста, помогите

Директор, который я хочу отслеживать, имеет несколько подпапок. Каждая подпапка имеет другую подпапку, которая может в какой-то момент содержать файл. MainFolder-> Подпапки-> каждая подпапка-> подпапка -> файл.

Вот код, который у меня есть на данный момент:

/*


*/
  #include <pthread.h>
    #include <unistd.h>

#include <iostream>
#include <sys/inotify.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/inotify.h>
#include <vector>
#include <string>
    #include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
using namespace std;
 vector<string> SS;



void *print_message_function( void *ptr );


int main(int argc, char **argv ){

  pthread_t t1;
    int fd,fd1,wd,wd1,i=0,i1=0,len=0,len1=0;
      int length;
    char pathname[100],buf[1024],buf1[1024];
   int data;
    struct inotify_event *event;
     char *message1 = "Thread 1";



   FILE *fr;
   // fd=inotify_init1(IN_NONBLOCK);//--rewrite
    fd = inotify_init();


    /* watch /test directory for any activity and report it back to me */
    wd=inotify_add_watch(fd,"/home/MainFoder/",IN_ALL_EVENTS);

  //  int flag=0;
   // char*ev="";
//wd=inotifytools_watch_recursively_with_exclude("/home/MainFolder/",IN_ALL_EVENTS);
 while(1)
{
//sleep(30);
        //read 1024  bytes of events from fd into buf

i=0;
        len=read(fd,buf,1024);
        while(i<len){

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


    /* watch /test directory for any activity and report it back to me */


            /* check for changes */
              {
            if((event->mask & IN_OPEN) ||(event->mask & IN_CREATE))

             {  


                 printf("\n %s :was opened\n",event->name);
                SS.push_back(event->name);



             }

       }
            /* update index to start of next event */
            i+=sizeof(struct inotify_event)+event->len;
        }

         vector<string>::const_iterator cii;
for(cii=SS.begin(); cii!=SS.end(); cii++)
       {


wd1 = watch_from_filename(*ci);
}
/*
vector<string>::const_iterator cii;
       for(cii=SS.begin(); cii!=SS.end(); cii++)
       {
          cout <<"HERE:"<< *cii << endl;
       }
*/
int  iret1, iret2;

    /* Create independent threads each of which will execute function */

     iret1 = pthread_create( &t1, NULL, print_message_function, (void*) message1);

}

}
void *print_message_function( void *ptr )
{
    vector<string>::const_iterator cii;
       for(cii=SS.begin(); cii!=SS.end(); cii++)
       {

          cout <<"HERE:"<< *cii << endl;
          std::string path=exec

       }
}

Ответы [ 5 ]

3 голосов
/ 17 июля 2013

Этот рабочий пример на Github делает то, что вы ищете: inotify-example.cpp

В событиях CREATE текущий wd (дескриптор просмотра), плюс inotify_event wd иКомпоненты name добавляются в объект Watch (см. пример).Класс включает методы для поиска wd и имен несколькими способами.

Этот фрагмент показывает, как обрабатываются события CREATE / DELETE:

            if ( event->mask & IN_CREATE ) {
                current_dir = watch.get(event->wd);
                if ( event->mask & IN_ISDIR ) {
                    new_dir = current_dir + "/" + event->name;
                    wd = inotify_add_watch( fd, new_dir.c_str(), WATCH_FLAGS );
                    watch.insert( event->wd, event->name, wd );
                    total_dir_events++;
                    printf( "New directory %s created.\n", new_dir.c_str() );
                } else {
                    total_file_events++;
                    printf( "New file %s/%s created.\n", current_dir.c_str(), event->name );
                }
            } else if ( event->mask & IN_DELETE ) {
                if ( event->mask & IN_ISDIR ) {
                    new_dir = watch.erase( event->wd, event->name, &wd );
                    inotify_rm_watch( fd, wd );
                    total_dir_events--;
                    printf( "Directory %s deleted.\n", new_dir.c_str() );
                } else {
                    current_dir = watch.get(event->wd);
                    total_file_events--;
                    printf( "File %s/%s deleted.\n", current_dir.c_str(), event->name );
                }
            }
1 голос
/ 13 января 2015

Я написал код для вас.Теперь вы должны сделать только одно изменение в этом коде.Просто укажите путь к вашему каталогу в основной функции.

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/inotify.h>
#include <limits.h>
#include<sys/stat.h>
#include<dirent.h>
#include<time.h>
#include<string.h>
#include<unistd.h>

#define MAX_EVENTS 1024 /*Max. number of events to process at one go*/
#define LEN_NAME 16 /*Assuming that the length of the filename won't exceed 16 bytes*/
#define EVENT_SIZE  ( sizeof (struct inotify_event) ) /*size of one event*/
#define BUF_LEN     ( MAX_EVENTS * ( EVENT_SIZE + LEN_NAME )) /*buffer to store the data of events*/

void monitor(char *);
int evnt_mon(char *); 




void main()
{
    if(fork()==0)
    evnt_mon("./usssb");// give path of your directory which you want to monitor
    monitor("./usssb");// give path of your directory which you want to monitor
    while(1);
}

void monitor(char * rt_dir)
{

    struct stat st;
    DIR *dirp; 
    struct dirent *dp;
    char str[100][100]={ };
    char temp[100];
    char str1[500]=" ";
    int i=0,j=0,src_ret=9,src_ret1=9;
    strcpy(str1,rt_dir);
    dirp=opendir(str1);
    if(dirp==NULL)
    {
        perror("opendir");
        return;
    }

    while(1)
    {
        dp=readdir(dirp);
        if(dp==NULL)
        break;
        if((strcmp(dp->d_name,".\0")==0) || (strcmp(dp->d_name,"..")==0))
        continue;   

        if((dp->d_type==DT_DIR)&&((strcmp(dp->d_name,".")!=0)&&(strcmp(dp->d_name,"..")!=0)))
        {   
            strcat(str[i],str1);
            strcat(str[i],"/");
            strcat(str[i],dp->d_name);
            if(fork()==0)   
            {
                evnt_mon(str[i]);
            }
            i++;
        }

    }

    closedir(dirp);
    if(i>0)
    {
        for(j=0;j<i;j++)
        {
            monitor(str[j]);    
        }
    }

}




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

    /* Initialize Inotify*/
    fd = inotify_init();
    if ( fd < 0 )
    {
        perror( "Couldn't initialize inotify");
    }

    /* add watch to starting directory */
    wd = inotify_add_watch(fd, argv, IN_CREATE | IN_MODIFY | IN_DELETE); 

    if (wd == -1)
    {
        printf("Couldn't add watch to %s\n",argv);
    }
    else
    {
        printf("Watching:: %s\n",argv);
    }

    /* do it forever*/
    while(1)
    {
        i = 0;
        length = read( fd, buffer, BUF_LEN );  
        if ( length < 0 )
        {
            perror( "read" );
        }  

        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( "The directory %s was Created in %s.\n", event->name,argv );    


                        if(fork()==0)
                        {
                            char p[100]=" ";
                            strcpy(p,argv);
                            strcat(p,"/");
                            strcat(p,event->name);
                            evnt_mon(p);
                        }

                    }                       
                    else
                            printf( "The file %s was Created with WD %d\n", event->name, event->wd );       
                    }

                    if ( event->mask & IN_MODIFY)
                {
                            if (event->mask & IN_ISDIR)
                            printf( "The directory %s was modified.\n", event->name );       
                            else
                            printf( "The file %s was modified with WD %d\n", event->name, event->wd );       
                    }

                    if ( event->mask & IN_DELETE)
                {
                            if (event->mask & IN_ISDIR)
                            printf( "The directory %s was deleted from %s.\n", event->name,argv );       
                            else
                            printf( "The file %s was deleted with WD %d\n", event->name, event->wd );       
                    }  

                i += EVENT_SIZE + event->len;
            }
            }
        }

    /* Clean up*/
    inotify_rm_watch( fd, wd );
    close( fd );

    return 0;
}
1 голос
/ 05 февраля 2012

Вы можете сделать это в два этапа:

  1. Обнаружение всех изменений, которые вас интересуют, в корневом каталоге, а также (если они еще не включены) созданий (IN_CREATE).
  2. Если создание является каталогом, выполните весь алгоритм для него.
0 голосов
/ 07 апреля 2018

Вы можете использовать API fanotify. Это позволяет вам контролировать полное крепление. Единственным недостатком является то, что вам нужно быть пользователем root.

0 голосов
/ 21 июля 2017

Для решения проблемы, указанной рибрамом («дыра» :)). одно возможное решение, о котором я могу подумать, это то, что мы можем сделать комбинацию «опроса каталога» и «использования inotify» ... т.е. каждый раз, когда каталог обнаруживается (только каталог, не делайте этого для файлов):

  • добавить точку наблюдения для недавно обнаруженного каталога для inotify
  • 'опросить' (или 'просканировать') только что обнаруженный каталог (man readdir ()), чтобы увидеть, созданы ли уже элементы (файлы, каталоги). Возможно, это те, которые отсутствуют.

Обратите внимание, что для создания «воздухонепроницаемого» корпуса важен порядок вышеуказанных шагов. вам нужно сначала добавить точку наблюдения, а не сканировать ... Это гарантирует, что элемент будет выбран при сканировании или inotify, или в обоих случаях. В этом случае вам также может понадобиться знать о дупсах. то есть один и тот же предмет может быть получен как сканированием, так и inotify

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...