Отслеживать каталог только для новых файлов - PullRequest
2 голосов
/ 04 ноября 2010

Я хотел бы отслеживать каталог для новых файлов из приложения на Си.Однако меня не интересуют измененные файлы, только новые файлы.В настоящее время я использую readdir / stat для этой цели:

while ( (ent = readdir(dir)) != NULL ) {
  strcpy(path, mon_dir);
  strcat(path, "/");
  strcat(path, ent->d_name);
  if ( stat(path, &statbuf) == -1 ) {
    printf( "Can't stat %s\n", ent->d_name );
    continue;
  }
  if ( S_ISREG(statbuf.st_mode) ) {
    if ( statbuf.st_mtime > *timestamp ) {
      tcomp = localtime( &statbuf.st_mtime );
      strftime( s_date, sizeof(s_date), "%Y%m%d %H:%M:%S", tcomp );
      printf( "%s %s was added\n", s_date, ent->d_name );
      *timestamp = statbuf.st_mtime;
    }
  }
}

Любая идея, как я могу обнаружить вновь созданные файлы на Linux AND Solaris 10 без сохранения списка файлов?

Ура,

Мартин.

Ответы [ 8 ]

7 голосов
/ 04 ноября 2010

gamin предоставляет абстракцию вокруг системно-зависимого файла уведомлений apis для многих * nixes и по умолчанию включена во многие дистрибутивы linux.

Для Linux вы можете использовать специфичные для Linux inotify api.

Win32 имеет похожий API через FindFirstChangeNotification

2 голосов
/ 05 ноября 2010

Решение состоит в том, чтобы сохранить время последнего доступа в глобальной переменной и выбрать последние файлы с фильтром в scandir():

int cmp_mtime( const struct dirent** lentry, const struct dirent** rentry ):

  1. Стат (*lentry)->d_name (расширен по пути, но это только деталь)
  2. ltime = statbuf.st_mtime;
  3. Стат (*rentry)->d_name (расширен по пути, но это только деталь)
  4. rtime = statbuf.st_mtime;
  5. if ( ltime < rtime ) return -1;
  6. else if ( ltime > rtime ) return 1;
  7. return 0;

int selector( const struct dirent* entry )

  1. Стат entry->d_name (расширен по пути, но это только деталь)
  2. Если файл не нормальный, вернуть 0
  3. Если stat.st_mtime > lastseen, вернуть 1, в противном случае вернуть 0

Main:

  1. Начальная глобальная переменная времени lastseen
  2. scandir( directory, &entries, selector, cmp_mtime );
  3. Обработка списка записей
  4. lastseen: = mtime последней записи в списке
2 голосов
/ 05 ноября 2010

Вероятно, нет лучшего способа, чтобы Solaris 10 взаимодействовал с командой dtrace или libdtrace (не рекомендуется). В ОС на базе SunOS 5.11 (например, OpenSolaris, Solaris 11 Express, ...) вы можете просто использовать Инфраструктура уведомления о файловых событиях .

1 голос
/ 04 ноября 2010

В MacOS X имеется API для мониторинга файлов , и в приведенном примере кода показано, как найти файлы, которые были изменены.

0 голосов
/ 28 июля 2013

Я знаю, что вы запрашивали решение от C, но на самом деле Java (сейчас) имеет кроссплатформенный класс для этого.Вы можете прочитать больше об этом здесь .Также см. Документацию для класса WatchService , который является центральным классом возможности уведомления об изменениях файлов в Java.

Возможно, где-то есть документация о том, как Java выполняет это на различных платформах?

Из всего, что я понимаю, Java использует собственный API уведомлений об изменениях файлов в ОС Linux, Solaris и Windows, а затем, кроме того, реализует резервный метод, основанный на опросе, который будет работать на любой платформе.

0 голосов
/ 28 июля 2013

Изучал ту же тему по Solaris и нашел пример приложения watchdir, которое будет использоваться из скриптов, как в

watchdir /foo/bar

, который выполнит блокировку, ожидая, пока что-то не произойдет с просматриваемым каталогом.

Ссылка: https://solarisrants.wordpress.com/2013/07/24/solaris-file-event-notification/

0 голосов
/ 04 ноября 2010

Для этого вы можете использовать FAM - монитор изменений файлов .

0 голосов
/ 04 ноября 2010

Одна хитрость может заключаться в установке бита архива для обработанных файлов.

Эдит говорит: если ничего из других ответов не помогло, вы можете поиграть с chmod ().

...