Как правильно использовать inotify?
Я хочу использовать inotify
механизм в Linux. Я хочу, чтобы мое приложение знало, когда файл . Можете ли вы предоставить мне образец, как это сделать?
4 ответов
- документация ( с мониторинг активности файловой системы с помощью в inotify )
API inotify C
Inotify предоставляет три системных вызова для создания мониторов файловой системы всех видов:
- inotify_init() создает экземпляр подсистемы inotify в ядре и возвращает дескриптор файла в случае успеха и -1 в случае неудачи. Как и другие системные вызовы, если inotify_init () не удается, проверьте errno для диагностика.
- inotify_add_watch (), как следует из его названия, добавляет часы. Каждый вахта должен предоставить путь и список соответствующих событий, где каждое событие задается константой, например IN_MODIFY. Чтобы отслеживать более одного события, просто используйте логический оператор or-pipe (|) в C-между каждым событием. Если inotify_add_watch() выполняется успешно, вызов возвращает уникальный идентификатор для зарегистрированных часов; в противном случае -1. Используйте идентификатор для изменения или удаления связанного часы.
- inotify_rm_watch() удаляет часы.
системные вызовы read() и close() также необходимы. Учитывая дескриптор, полученный inotify_init (), вызовите read () для ожидания предупреждений. Предполагая типичный файловый дескриптор, приложение блокирует ожидание получения событий, которые выражаются в виде данных в потоке. Общее close() в файловом дескрипторе, полученном из inotify_init (), удаляет и освобождает все активные часы, а также всю память, связанную с экземпляр inotify. (Типичное предостережение о количестве ссылок применяется и здесь. Все файловые дескрипторы, связанные с экземпляром, должны быть закрыты до освобождения памяти, потребляемой часами и inotify.)
- пример ( из Kernel Korner-вступление к в inotify )
#include "inotify.h" #include "inotify-syscalls.h" int wd; wd = inotify_add_watch (fd, "/home/rlove/Desktop", IN_MODIFY | IN_CREATE | IN_DELETE); if (wd < 0) perror ("inotify_add_watch");
этот пример добавляет часы в каталоге / home/rlove / Desktop для любых изменений, создания файлов или удаления файлов.
Ниже приведен фрагмент того, как вы можете использовать inotify для просмотра "aaa". Обратите внимание, что я не тестировал это, я даже не скомпилировал его! Вам нужно будет добавить к нему проверку ошибок.
вместо использования блокирующего чтения вы также можете использовать poll / select на inotfd.
const char *filename = "aaa";
int inotfd = inotify_init();
int watch_desc = inotify_add_watch(inotfd, filename, IN_MODIFY);
size_t bufsiz = sizeof(struct inotify_event) + PATH_MAX + 1;
struct inotify_event* event = malloc(bufsiz);
/* wait for an event to occur */
read(inotfd, event, bufsiz);
/* process event struct here */
поскольку первоначальный вопрос, похоже, упоминает Qt как тег, как отмечено в нескольких комментариях здесь, поисковые системы могут привести вас сюда.
Если кто-то хочет знать, как это сделать с Qt, см. http://doc.qt.io/qt-5/qfilesystemwatcher.html для Qt-версии. В Linux он использует подмножество Inotify, если оно доступно, см. объяснение на странице Qt для деталей.
В основном необходимый код выглядит так:
в главном окне.ч добавить :
QFileSystemWatcher * watcher;
private slots:
void directoryChanged(const QString & path);
void fileChanged(const QString & path);
и для главного окна.cpp:
#include <QFileInfo>
#include <QFileSystemWatcher>
watcher = new QFileSystemWatcher(this);
connect(watcher, SIGNAL(fileChanged(const QString &)), this, SLOT(fileChanged(const QString &)));
connect(watcher, SIGNAL(directoryChanged(const QString &)), this, SLOT(directoryChanged(const QString &)));
watcher->addPath("/tmp/"); // watch directory
watcher->addPath("/tmp/a.file"); // watch file
также добавьте слоты в mainwindow.cpp, которые вызываются, если замечено изменение файла / каталога:
void MainWindow::directoryChanged(const QString & path) {
qDebug() << path;
}
void MainWindow::fileChanged(const QString & path) {
qDebug() << path;
}
зачем изобретать велосипед? уже есть приложение под названием inotifywait
, который смотрит файлы с помощью inotify
из Терминала 1
# touch cheese
# while inotifywait -e modify cheese; do
> echo someone touched my cheese
> done
из Терминала 2
echo lol >> cheese
вот что видно на терминале 1
Setting up watches.
Watches established.
cheese MODIFY
someone touched my cheese
Setting up watches.
Watches established.