Quelle est la bonne façon d’utiliser inotify?

Je veux utiliser le mécanisme inotify sur Linux. Je veux que mon application sache quand un fichier aaa été modifié. Pouvez-vous s’il vous plaît me fournir un échantillon comment faire cela?

  • Documentation (à partir de l’ activité du système de fichiers Monitor avec inotify )

L’API C inotify
Inotify fournit trois appels système pour créer des moniteurs de système de fichiers de toutes sortes:

  • inotify_init () crée une instance du sous-système inotify dans le kernel et renvoie un descripteur de fichier en cas de succès et -1 en cas d’échec. Comme pour les autres appels système, si inotify_init () échoue, vérifiez errno pour les diagnostics.
  • inotify_add_watch (), comme son nom l’indique, ajoute une montre. Chaque surveillance doit fournir un chemin d’access et une liste d’événements pertinents, où chaque événement est spécifié par une constante, telle que IN_MODIFY. Pour surveiller plusieurs événements, utilisez simplement l’opérateur logique ou-the pipe (|) dans C-between chaque événement. Si inotify_add_watch () réussit, l’appel renvoie un identifiant unique pour la montre enregistrée; sinon, il retourne -1. Utilisez l’identifiant pour modifier ou supprimer la montre associée.
  • inotify_rm_watch () supprime une montre.

Les appels système read () et close () sont également nécessaires. Compte tenu du descripteur généré par inotify_init (), appelez read () pour attendre les alertes. En supposant un descripteur de fichier typique, l’application se bloque en attendant la réception des événements, qui sont exprimés sous forme de données dans le stream. Le commun close () du descripteur de fichier généré par inotify_init () supprime et libère toutes les montres actives ainsi que toute la mémoire associée à l’instance inotify. (La condition de décompte de référence typique s’applique également ici. Tous les descripteurs de fichiers associés à une instance doivent être fermés avant que la mémoire consommée par les montres et par inotify ne soit libérée.)

  • Un exemple (de Kernel Korner – Intro 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"); 

Cet exemple ajoute une surveillance sur le répertoire / home / rlove / Desktop pour toute modification, création de fichier ou suppression de fichier.

Voici un extrait de la façon dont vous pouvez utiliser inotify pour regarder “aaa”. Notez que je n’ai pas testé cela, je ne l’ai même pas compilé! Vous devrez y append une vérification d’erreur.

Au lieu d’utiliser une lecture bloquante, vous pouvez également utiliser poll / select sur 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 */ 

Comme la question initiale semble mentionner Qt comme un tag, comme noté dans plusieurs commentaires ici, les moteurs de recherche peuvent vous avoir amené ici.

Si quelqu’un veut savoir comment faire avec Qt, voir http://doc.qt.io/qt-5/qfilesystemwatcher.html pour la version Qt. Sous Linux, il utilise un sous-ensemble d’Inotify, s’il est disponible, voir les explications sur la page Qt pour plus de détails.

Fondamentalement, le code nécessaire ressemble à ceci:

dans mainwindow.h append:

 QFileSystemWatcher * watcher; private slots: void directoryChanged(const QSsortingng & path); void fileChanged(const QSsortingng & path); 

et pour mainwindow.cpp:

 #include  #include  watcher = new QFileSystemWatcher(this); connect(watcher, SIGNAL(fileChanged(const QSsortingng &)), this, SLOT(fileChanged(const QSsortingng &))); connect(watcher, SIGNAL(directoryChanged(const QSsortingng &)), this, SLOT(directoryChanged(const QSsortingng &))); watcher->addPath("/tmp/"); // watch directory watcher->addPath("/tmp/a.file"); // watch file 

Ajoutez également les slots dans mainwindow.cpp qui sont appelés si un changement de fichier / répertoire est remarqué:

 void MainWindow::directoryChanged(const QSsortingng & path) { qDebug() << path; } void MainWindow::fileChanged(const QString & path) { qDebug() << path; } 

pourquoi réinventer la roue? il existe déjà une application appelée inotifywait qui surveille les fichiers en utilisant inotify

du terminal 1

 # touch cheese # while inotifywait -e modify cheese; do > echo someone touched my cheese > done 

du terminal 2

 echo lol >> cheese 

voici ce que l’on voit sur le terminal 1

 Setting up watches. Watches established. cheese MODIFY someone touched my cheese Setting up watches. Watches established.