在Windows 7 64位计算机上使用python 2.7。
如何获取文件关闭事件:
那么,在上述情况下如何获取文件关闭事件?是否可以通过公共代码实现上述情况?我正在处理不同的文件类型
答案 0 :(得分:16)
对于* nix系统来说,事实证明这是一项非常简单的任务,但在Windows上,获取文件关闭事件并不是一项简单的任务。请阅读以下按OS' es。
分组的常用方法摘要在Linux上,可以轻松监控文件系统更改,并且非常详细。最好的工具是名为inotify
的内核功能,并且有一个使用它的Python实现,称为Pynotify。
Pyinotify
是一个用于监视文件系统更改的Python模块。 Pyinotify依赖于一个名为inotify
的Linux内核功能(在内核2.6.13中合并),它是一个事件驱动的通知程序。其通知通过三个系统调用从内核空间导出到用户空间。 Pyinotify
绑定这些系统调用,并在它们之上提供一个实现,提供一种通用和抽象的方式来操作这些功能。
Here您可以找到可以使用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
。有关详细信息,请访问documentation
Windows上的Watchdog依赖于ReadDirectoryChangesW
API,它会像Watcher和其他依赖相同API的库一样引起注意。
Linux watch
命令的python near-clone。可以告诉pywatch.watcher.Watcher
类监视一组文件,并在任何这些文件发生更改时给出一组命令来运行。它只能监视文件更改事件,因为它依赖于轮询stat's st_mtime。
NTFS USN(更新序列号)日志是NTFS的一项功能,它保留对卷所做更改的记录。它被列为 Bonus 的原因是因为与其他条目不同,它不是特定的库,而是NTFS系统上存在的特性。因此,如果您使用其他Windows文件系统(如FAT,ReFS等),则不适用 它的工作方式是系统记录USN Journal文件中对卷所做的所有更改,每个卷都有自己的实例。 “更改日志”中的每条记录都包含USN,文件名以及有关更改内容的信息。
此方法对此问题感兴趣的主要原因是,与大多数其他方法不同,此方法提供了一种检测文件关闭事件的方法,定义为 USN_REASON_CLOSE 。有关完整事件列表的更多信息,请参阅此MSDN article。有关USN日记功能的完整文档,请访问此MSDN page。
有多种方法可以从Python访问USN Journal,但唯一成熟的选项似乎是 ntfsjournal 模块。
正如MSDN page所述:
文件系统过滤器驱动程序是一个可添加值的可选驱动程序 或修改文件系统的行为。文件系统筛选器驱动程序 是一个内核模式组件,作为Windows执行程序的一部分运行。 文件系统筛选器驱动程序可以筛选一个或多个I / O操作 文件系统或文件系统卷。取决于性质 驱动程序,过滤器可能意味着记录,观察,修改甚至阻止。典型 文件系统筛选器驱动程序的应用程序包括防病毒 实用程序,加密程序和分层存储管理 系统
实现文件系统过滤器驱动程序并不是一件容易的事,但对于想尝试一下的人来说,有一个很好的介绍教程CodeProject。
P.S。请查看@ixe013's answer以获取有关此方法的其他信息。
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_()
答案 1 :(得分:3)
您面临的问题不是Python,而是Windows。它可以完成,但你必须为它编写一些非trival C / C ++代码。
Windows上的userland中不存在文件打开或文件关闭用户模式通知。这就是为什么其他人建议的图书馆没有文件关闭通知的原因。在Windows中,用于检测用户空间更改的API为ReadDirectoryChangesW。它会提醒您one of the following notifications:
FILE_ACTION_ADDED
如果文件已添加到目录中。FILE_ACTION_REMOVED
如果文件已从目录中删除。FILE_ACTION_MODIFIED
如果文件被修改。这可以是时间戳或属性的更改。FILE_ACTION_RENAMED_OLD_NAME
如果文件已重命名且这是旧名称。FILE_ACTION_RENAMED_NEW_NAME
如果文件已重命名且这是新名称。没有多少Python可以改变Windows为您提供的功能。
要获取文件关闭通知,tools like Process Monitor安装Minifilter that lives in the kernel,靠近EFS等其他过滤器的顶部。
要获得你想要的东西,你需要:
user
程序中的代码,使其成为Python扩展(minispy.pyd
),公开生成事件的生成器。这是困难的部分,我会回过头来看。整件事看起来像这样:
当然你可以将EFS超过NTFS,这只是为了表明你的微过滤器将超越所有。
困难的部分:
最后两个是最难的。
答案 2 :(得分:1)
您可以使用Pyfanotyfi或butter。
我认为您会发现此链接非常有用:Linux file system events with C, Python and Ruby
在那里你会找到一个关于做你想做的事情的例子(使用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()
答案 3 :(得分:0)
我还没有找到在Windows上捕获open
和close
事件的程序包。正如其他人所提到的,pyinotify是基于Linux的操作系统的绝佳选择。
由于我无法观看已结束的活动,因此我选择了修改后的活动。事实上,这是一个非常重要的事情。解决方案的类型(即,在我看到文件关闭之前,我无法暂停)。但是,这种方法效果出奇的好。
我已经使用了watchdog套餐。下面的代码来自他们的sample实现,如果您没有在命令行上传递路径,则会监视当前目录,否则它会监视您传递的路径。
示例通话: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
event即可进行过滤。