我有一个日志文件正在写的另一个进程,我想观察变化。每次发生更改时,我都希望将新数据读入并对其进行一些处理。

最好的方法是什么?我希望在PyWin32库中有某种钩子。我找到了win32文件。函数FindNextChangeNotification,但不知道如何要求它监视特定的文件。

如果有人做过类似的事情,我真的很感激能听到…

[编辑]我应该提到我追求的是一种不需要轮询的解决方案。

[编辑]诅咒!这似乎不能在映射的网络驱动器上工作。我猜windows不会像在本地磁盘上那样“听到”任何对文件的更新。


当前回答

看看我对类似问题的回答。您可以在Python中尝试相同的循环。本页建议:

import time

while 1:
    where = file.tell()
    line = file.readline()
    if not line:
        time.sleep(1)
        file.seek(where)
    else:
        print line, # already has newline

还可以使用Python查看文件中的问题tail()。

其他回答

我会尝试这样的方法。

    try:
            f = open(filePath)
    except IOError:
            print "No such file: %s" % filePath
            raw_input("Press Enter to close window")
    try:
            lines = f.readlines()
            while True:
                    line = f.readline()
                    try:
                            if not line:
                                    time.sleep(1)
                            else:
                                    functionThatAnalisesTheLine(line)
                    except Exception, e:
                            # handle the exception somehow (for example, log the trace) and raise the same exception again
                            raw_input("Press Enter to close window")
                            raise e
    finally:
            f.close()

循环检查自上次读取文件以来是否有新的行——如果有,则将其读取并传递给functionThatAnalisesTheLine函数。如果不是,脚本等待1秒并重试该进程。

看看pyinotify。

Inotify在新的linux中取代了dnotify(从以前的答案),并允许文件级而不是目录级监控。

watchfiles (https://github.com/samuelcolvin/watchfiles)是一个Python API和CLI,它使用了用Rust编写的Notify (https://github.com/notify-rs/notify)库。

rust实现目前(2022-10-09)支持:

Linux / Android: inotify macOS: FSEvents或kqueue,参见特性 Windows: ReadDirectoryChangesW FreeBSD / NetBSD / OpenBSD / DragonflyBSD: kqueue 所有平台:投票

可以在PyPI (https://pypi.org/project/watchfiles/)和conda-forge (https://github.com/conda-forge/watchfiles-feedstock)上获得二进制文件。

如果您想要一个多平台解决方案,那么请检查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)

这是一个检查文件更改的示例。这可能不是最好的方法,但肯定是一条捷径。

方便的工具,重新启动应用程序时,已作出更改的源。我在玩pygame的时候做了这个,这样我就可以看到文件保存后立即发生的效果。

当在pygame中使用时,确保'while'循环中的东西被放置在你的游戏循环中,也就是更新或其他什么。否则你的应用将陷入无限循环,你将看不到游戏的更新。

file_size_stored = os.stat('neuron.py').st_size

  while True:
    try:
      file_size_current = os.stat('neuron.py').st_size
      if file_size_stored != file_size_current:
        restart_program()
    except: 
      pass

如果你想要重启代码我在网上找到的。在这儿。(与问题无关,但可能会派上用场)

def restart_program(): #restart application
    python = sys.executable
    os.execl(python, python, * sys.argv)

让电子做你想让它们做的事情。