Вопрос-Ответ

How do I watch a file for changes?

Как мне просмотреть файл на предмет изменений?

У меня есть файл журнала, записываемый другим процессом, который я хочу просмотреть на предмет изменений. Каждый раз, когда происходит изменение, я хотел бы прочитать новые данные, чтобы выполнить некоторую обработку.

Какой лучший способ сделать это? Я надеялся, что будет какой-нибудь хук из библиотеки PyWin32. Я нашел win32file.FindNextChangeNotification функцию, но понятия не имею, как попросить ее просмотреть определенный файл.

Если кто-нибудь делал что-либо подобное, я был бы очень признателен услышать, как это делается...

[Редактировать] Мне следовало упомянуть, что я искал решение, которое не требует опроса.

[Редактировать] Проклятия! Похоже, это не работает на подключенном сетевом диске. Я предполагаю, что Windows не "слышит" никаких обновлений файла так, как это происходит на локальном диске.

Переведено автоматически
Ответ 1

Вы пробовали использовать Watchdog?


Библиотека Python API и утилиты оболочки для мониторинга событий файловой системы.


Мониторинг каталогов упростился с помощью



  • Кроссплатформенный API.

  • Инструмент оболочки для запуска команд в ответ на изменения каталога.


Быстро приступайте к работе с простым примером в Quickstart...


Ответ 2

Если опрос вас устраивает, я бы просто посмотрел, изменится ли статистика файла "измененное время". Чтобы прочитать ее:

os.stat(filename).st_mtime

(Также обратите внимание, что встроенное в Windows решение для событий изменения работает не во всех случаях, например, на сетевых дисках.)

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...
Ответ 3

Если вам нужно мультиплатформенное решение, тогда проверьте QFileSystemWatcher. Вот пример кода (не очищенный):

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)
Ответ 4

Это не должно работать в Windows (возможно, с cygwin ?), Но для пользователя unix вам следует использовать системный вызов "fcntl". Вот пример на Python. В основном это тот же код, если вам нужно написать его на C (те же имена функций)

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)
python windows file