如何获得文件closures事件:
那么,如何在上述情况下获得文件closures事件呢? 是否有可能通过一个共同的代码来实现上述情况? 我正在处理不同的文件types
这对于nix系统来说已经被证明是非常简单的任务,但是在Windows上,获取文件关闭事件并不是一件简单的事情。 请阅读下面按操作系统分组的常用方法的总结。
在Linux上,可以很容易地监视文件系统的变化,并且非常详细。 最好的工具是称为inotify
的内核特性,并且有一个使用它的Python实现,称为Pynotify。
Pyinotify
是一个用于监视文件系统更改的Python模块。 Pyinotify依靠一个名为inotify
的Linux内核功能(在内核2.6.13中合并),这是一个事件驱动的通知程序。 它的通知通过三个系统调用从内核空间导出到用户空间。 Pyinotify
绑定这些系统调用,并提供一个实现,提供一个通用的抽象方式来操纵这些功能。
在这里你可以找到Pynotify
可以监控的事件列表。
用法示例:
导入pyinotify
class EventHandler(pyinotify.ProcessEvent): def process_IN_CLOSE_NOWRITE(self, event): print "File was closed without writing: " + event.pathname def process_IN_CLOSE_WRITE(self, event): print "File was closed with writing: " + event.pathname def watch(filename): wm = pyinotify.WatchManager() mask = pyinotify.IN_CLOSE_NOWRITE | pyinotify.IN_CLOSE_WRITE wm.add_watch(filename, mask) eh = EventHandler() notifier = pyinotify.Notifier(wm, eh) notifier.loop() if __name__ == '__main__': watch('/path/to/file')
Windows的情况比Linux要复杂得多。 大多数库依赖于ReadDirectoryChanges
API,它是受限制的,不能检测到文件关闭事件等更精细的细节。 然而,还有其他的方法来检测这样的事件,所以请继续阅读以了解更多。
注意: Watcher已于2011年2月上次更新,所以可能会安全地跳过这个。
Watcher
是一个低级C
扩展,用于在Windows系统上使用ReadDirectoryChangesW
API接收文件系统更新。 该软件包还包含一个模拟大部分.NET FileSystemWatcher
API的高级界面。
与Watcher最近的一个可以检测文件关闭事件是监视FILE_NOTIFY_CHANGE_LAST_WRITE
和/或FILE_NOTIFY_CHANGE_LAST_ACCESS
事件。
用法示例:
import watcher w = watcher.Watcher(dir, callback) w.flags = watcher.FILE_NOTIFY_CHANGE_LAST_WRITE w.start()
Python API和shell实用程序来监视文件系统事件。 安装简单: $ pip install watchdog
。 欲了解更多信息,请访问文档 。
Windows上的看门狗依赖于ReadDirectoryChangesW
API,这就像Watcher和其他依赖于相同API的库一样引起了警告。
Linux watch
命令的Python近似克隆。 pywatch.watcher.Watcher
类可以被告知要观察一组文件,并给予一组命令来运行,只要这些文件中的任何一个改变。 它只能监视文件更改的事件,因为它依靠轮询stat的st_mtime 。
NTFS USN(更新序列号)日志是NTFS的一项功能,它维护对卷进行更改的记录。 它被列为奖金的原因是因为不像其他条目,它不是一个特定的库,而是一个存在于NTFS系统上的功能。 所以,如果你使用其他Windows文件系统(如FAT,ReFS等),这不适用。
它的工作方式是系统记录对USN日志文件中的卷进行的所有更改,每个卷都有自己的实例。 “更改日志”中的每个记录都包含USN,文件的名称以及有关更改内容的信息。
这个方法对于这个问题很有意思的主要原因是,与其他方法不同,这个方法提供了一种检测文件关闭事件的方法,定义为USN_REASON_CLOSE 。 有关完整的事件列表的更多信息可以在MSDN文章中找到。 有关USN日记的完整文档,请访问此MSDN页面 。
从Python访问USN日志有多种方式,但唯一成熟的选择似乎是ntfsjournal模块。
正如在MSDN页面上所描述的那样:
文件系统筛选器驱动程序是一个可选的驱动程序,它可以增加或修改文件系统的行为。 文件系统过滤器驱动程序是作为Windows执行程序的一部分运行的内核模式组件。 文件系统筛选器驱动程序可以筛选一个或多个文件系统或文件系统卷的I / O操作。 根据驱动程序的性质,过滤器可能意味着记录,观察,修改甚至阻止。 文件系统过滤驱动程序的典型应用程序包括防病毒实用程序,加密程序和分层存储管理系统。
实现一个文件系统过滤器驱动程序并不是一件容易的事情,但对于一个想尝试的人来说, CodeProject上有一个很好的入门教程。
PS检查@ ixe013的答案关于这个方法的一些额外的信息。
QFileSystemWatcher
类提供了一个监视文件和目录进行修改的接口。 这个类是在Qt 4.2
中引入的。
不幸的是,它的功能是相当有限的,因为它只能检测到一个文件已被修改,重命名或删除,以及当一个新的文件被添加到一个目录。
用法示例:
import sys from PyQt4 import QtCore def directory_changed(path): print('Directory Changed: %s' % path) def file_changed(path): print('File Changed: %s' % path) app = QtCore.QCoreApplication(sys.argv) paths = ['/path/to/file'] fs_watcher = QtCore.QFileSystemWatcher(paths) fs_watcher.directoryChanged.connect(directory_changed) fs_watcher.fileChanged.connect(file_changed) app.exec_()
你面临的问题不是Python,而是Windows。 它可以完成,但是你将不得不为它编写一些非平凡的C / C ++代码。
Windows上的userland中不存在文件打开或文件关闭用户模式通知。 这就是为什么其他人建议的图书馆没有文件关闭通知。 在Windows中,用于检测用户区更改的API是ReadDirectoryChangesW 。 它会提醒您以下通知之一 :
FILE_ACTION_ADDED
如果文件被添加到目录。 FILE_ACTION_REMOVED
是否从目录中删除文件。 FILE_ACTION_MODIFIED
如果文件被修改。 这可能是时间戳或属性的变化。 FILE_ACTION_RENAMED_OLD_NAME
如果文件被重命名,这是旧名称。 FILE_ACTION_RENAMED_NEW_NAME
如果文件被重命名,并且这是新名称。 没有多少Python可以改变Windows提供给你的东西。
要获得文件关闭通知, 像Process Monitor这样的工具会安装一个Minifilter,它驻留在内核中 ,靠近EFS等其他过滤器的顶部。
为了达到你想要的,你需要:
user
程序中的代码,使其成为一个Python扩展( minispy.pyd
),公开一个生成事件的生成器。 这是困难的部分,我会回到这一点。 整个事情看起来像这样:
当然你可以通过NTFS使用EFS,这只是为了表明你的微型过滤器将超越所有的。
困难的部分:
最后两个是最难的。
你可以使用Pyfanotyfi或黄油 。
我想你会发现这个链接非常有用: 与C,Python和Ruby的Linux文件系统事件
在那里你会找到一个关于做你想要的东西(使用pyinotify )的例子,这是代码:
import pyinotify DIR_TO_WATCH="/tmp/notify-dir" FILE_TO_WATCH="/tmp/notify-dir/notify-file.txt" wm = pyinotify.WatchManager() dir_events = pyinotify.IN_DELETE | pyinotify.IN_CREATE file_events = pyinotify.IN_OPEN | pyinotify.IN_CLOSE_WRITE | pyinotify.IN_CLOSE_NOWRITE class EventHandler(pyinotify.ProcessEvent): def process_IN_DELETE(self, event): print("File %s was deleted" % event.pathname) #python 3 style print function def process_IN_CREATE(self, event): print("File %s was created" % event.pathname) def process_IN_OPEN(self, event): print("File %s was opened" % event.pathname) def process_IN_CLOSE_WRITE(self, event): print("File %s was closed after writing" % event.pathname) def process_IN_CLOSE_NOWRITE(self, event): print("File %s was closed after reading" % event.pathname) event_handler = EventHandler() notifier = pyinotify.Notifier(wm, event_handler) wm.add_watch(DIR_TO_WATCH, dir_events) wm.add_watch(FILE_TO_WATCH, file_events) notifier.loop()
我还没有找到一个在Windows上捕获open
和close
事件的软件包。 正如其他人所说, pyinotify ,对于基于Linux的操作系统来说是一个很好的选择。
由于我无法观看封闭的事件,我决定修改事件。 这是一个“事后”类型的解决方案(即,我不能暂停,直到我看到一个文件被关闭)。 但是,这个工作出人意料的好。
我使用了看门狗软件包。 下面的代码来自它们的示例实现,并且如果不在命令行中传递路径,则会观察当前目录,否则它将监视传递的路径。
示例调用: python test.py
或python test.py C:\Users\Administrator\Desktop
import sys import time import logging from watchdog.observers import Observer from watchdog.events import LoggingEventHandler if __name__ == "__main__": logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S') path = sys.argv[1] if len(sys.argv) > 1 else '.' event_handler = LoggingEventHandler() observer = Observer() observer.schedule(event_handler, path, recursive=True) observer.start() try: while True: time.sleep(1) except KeyboardInterrupt: observer.stop() observer.join()
此代码将显示文件的创建,修改,删除或重命名/移动。 你可以通过修改on_modified
事件来进行过滤。