419 Stimmen

Wie kann ich eine Datei auf Änderungen überwachen?

Ich habe eine Protokolldatei, die von einem anderen Prozess geschrieben wird und die ich auf Änderungen überwachen möchte. Jedes Mal, wenn eine Änderung auftritt, möchte ich die neuen Daten einlesen, um sie zu verarbeiten.

Wie kann man das am besten machen? Ich hatte gehofft, es gäbe eine Art von Haken von der PyWin32-Bibliothek. Ich habe die win32file.FindNextChangeNotification Funktion, weiß aber nicht, wie man sie auffordert, eine bestimmte Datei zu überwachen.

Wenn jemand so etwas schon einmal gemacht hat, wäre ich sehr dankbar zu erfahren, wie...

[Bearbeiten] Ich hätte erwähnen sollen, dass ich eine Lösung gesucht habe, die keine Abfrage erfordert.

[Bearbeiten] Verflucht! Es scheint, dass dies nicht über ein gemapptes Netzlaufwerk funktioniert. Ich vermute, dass Windows die Aktualisierungen der Datei nicht wie bei einem lokalen Laufwerk "mitbekommt".

330voto

simao Punkte 12981

Haben Sie versucht, mit Watchdog ?

Python-API-Bibliothek und Shell-Dienstprogramme zur Überwachung von Dateisystemereignissen.

Verzeichnisüberwachung leicht gemacht mit

  • Eine plattformübergreifende API.
  • Ein Shell-Tool zur Ausführung von Befehlen als Reaktion auf Verzeichnisänderungen.

Machen Sie den Anfang mit einem einfachen Beispiel in Schnellstart ...

136voto

Deestan Punkte 15779

Wenn die Abfrage für Sie ausreichend ist, würde ich einfach beobachten, ob sich die Dateistatistik "Modified Time" ändert. Um sie zu lesen:

os.stat(filename).st_mtime

(Beachten Sie auch, dass die Windows-eigene Lösung für Änderungsereignisse nicht unter allen Umständen funktioniert, z. B. bei Netzlaufwerken).

import os

class Monkey(object):
    def __init__(self):
        self._cached_stamp = 0
        self.filename = '/path/to/file'

    def ook(self):
        stamp = os.stat(self.filename).st_mtime
        if stamp != self._cached_stamp:
            self._cached_stamp = stamp
            # File has changed, so do something...

82voto

Horst Gutmann Punkte 10092

Haben Sie sich bereits die Dokumentation angesehen, die unter http://timgolden.me.uk/python/win32_how_do_i/watch_directory_for_changes.html ? Wenn es nur unter Windows funktionieren soll, scheint das 2. Beispiel genau das zu sein, was Sie wollen (wenn Sie den Pfad des Verzeichnisses mit einer der Dateien austauschen, die Sie beobachten wollen).

Andernfalls wird die Umfrage wahrscheinlich die einzige wirklich plattformunabhängige Option sein.

Anmerkung: Ich habe keine dieser Lösungen ausprobiert.

60voto

hipersayan_x Punkte 531

Wenn Sie eine plattformübergreifende Lösung wünschen, dann prüfen Sie QFileSystemWatcher . Hier ein Beispielcode (nicht bereinigt):

from PyQt4 import QtCore

@QtCore.pyqtSlot(str)
def directory_changed(path):
    print('Directory Changed!!!')

@QtCore.pyqtSlot(str)
def file_changed(path):
    print('File Changed!!!')

fs_watcher = QtCore.QFileSystemWatcher(['/path/to/files_1', '/path/to/files_2', '/path/to/files_3'])

fs_watcher.connect(fs_watcher, QtCore.SIGNAL('directoryChanged(QString)'), directory_changed)
fs_watcher.connect(fs_watcher, QtCore.SIGNAL('fileChanged(QString)'), file_changed)

35voto

Maxime Punkte 1948

Unter Windows sollte es nicht funktionieren (vielleicht mit cygwin?), aber für Unix-Benutzer sollten Sie den Systemaufruf "fcntl" verwenden. Hier ist ein Beispiel in Python. Es ist größtenteils der gleiche Code, wenn Sie ihn in C schreiben müssen (gleiche Funktionsnamen)

import time
import fcntl
import os
import signal

FNAME = "/HOME/TOTO/FILETOWATCH"

def handler(signum, frame):
    print "File %s modified" % (FNAME,)

signal.signal(signal.SIGIO, handler)
fd = os.open(FNAME,  os.O_RDONLY)
fcntl.fcntl(fd, fcntl.F_SETSIG, 0)
fcntl.fcntl(fd, fcntl.F_NOTIFY,
            fcntl.DN_MODIFY | fcntl.DN_CREATE | fcntl.DN_MULTISHOT)

while True:
    time.sleep(10000)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X