Frage

Ich möchte den inotify Mechanismus auf Linux verwenden. Ich möchte meine Anwendung wissen, wann eine Datei aaa geändert wurde. Können Sie mir bitte mit einer Probe zur Verfügung stellen, wie das zu tun?

War es hilfreich?

Lösung

Die inotify C API

inotify bietet drei Systemaufrufe zu bauen Dateisystem überwacht aller Art:

  • inotify_init() erstellt eine Instanz des inotify Subsystem im Kernel und gibt einen Dateideskriptor auf Erfolg und -1 ein Fehler auftrat. Wie andere Systemaufrufe, wenn inotify_init() fehlschlägt, überprüfen errno für die Diagnose.
  • inotify_add_watch(), wie der Name schon sagt, fügt eine Uhr . Jede Uhr muss einen Pfadnamen und eine Liste der relevanten Ereignisse liefern, wobei jedes Ereignis durch eine Konstante angegeben wird, wie IN_MODIFY. Um mehr als ein Ereignis zu überwachen, verwenden Sie einfach die logische oder - das Rohr (|) Operator in C-zwischen jedem Ereignis. Wenn inotify_add_watch() erfolgreich ist, gibt der Aufruf eine eindeutige Kennung für die registrierte Uhr; Andernfalls gibt es -1. Verwenden Sie die Kennung zu ändern oder die zugehörige Uhr zu entfernen.
  • inotify_rm_watch() entfernt eine Uhr.

Die read() und close() Systemaufrufe werden ebenfalls benötigt. In Anbetracht der Beschreiber, erhalten durch inotify_init(), Call read() auf für Benachrichtigungen zu warten. Unter der Annahme einer typischen Dateideskriptor, die Applikationsblöcke den Empfang der Ereignisse der Warteschlange, die als Daten in dem Strom exprimiert werden. Der gemeinsame close () auf dem Dateideskriptor von Löschungen inotify_init() ergab und gibt alle aktiven Uhren sowie alle mit der inotify Instanz zugeordneten Speicher. (Der typische Referenzzähler Vorbehalt gilt auch hier. Alle Datei-Deskriptoren mit einer Instanz verbunden ist, müssen geschlossen werden, bevor der Speicher durch die Uhr verbraucht und durch inotify befreit wird.)

#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");

In diesem Beispiel wird eine Uhr auf dem Verzeichnis / home / RLove / Desktop für Umstellungen, Datei-Kreationen oder Löschen von Dateien.

Andere Tipps

Im Folgenden ist ein Ausschnitt aus wie Sie inotify zu sehen „aaa“ verwenden können. Beachten Sie, dass ich nicht getestet habe, habe ich es nicht einmal zusammengestellt! Sie müssen die Fehlerprüfung, um es hinzuzufügen.

Statt eine Sperrung der Verwendung lesen Sie auch Umfrage / select auf inotfd verwenden können.

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 */

Wenn alles, was Sie brauchen, ist ein Kommandozeilen-Anwendung ist, gibt es eine namens inotifywait dass Uhren Dateien inotify

mit

vom Terminal 1

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

vom Terminal 2

echo lol >> cheese

Hier ist das, was auf dem Terminal 1 zu sehen ist,

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

Aktualisieren :. Verwendung nur mit Vorsicht und sehen Sie die Kommentare

Da die anfängliche Frage Qt als Tag zu erwähnen scheint, als hier in mehreren Stellungnahmen wird darauf hingewiesen, Suchmaschinen, die Sie hier führen kann.

Wenn jemand möchte wissen, wie es mit Qt zu tun, sehen http://doc.qt.io/qt-5/qfilesystemwatcher.html für die Qt-Version. Unter Linux verwendet es eine Teilmenge von Inotify, wenn es verfügbar ist, siehe die Erklärung auf der Qt-Seite für Details.

Grundsätzlich sind die benötigten Code sieht wie folgt aus:

in mainwindow.h add:

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

und für mainwindow.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

fügen Sie auch die Schlitze in mainwindow.cpp, die aufgerufen werden, wenn eine Datei / Verzeichnis-Änderung bemerkt wird:

void MainWindow::directoryChanged(const QString & path) {
     qDebug() << path;
}
void MainWindow::fileChanged(const QString & path) {
     qDebug() << path;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top