简短版本:我编写/改编的 Python 脚本,用于在修改文件时监视目录的更改触发两次。为什么?
长版:
我正在编写一些 Python 代码来监视目录及其子目录的更改。
(出于企业 IT 的原因,我不适合使用 Python Watchdog 包。)
从那里的例子中剪切和粘贴:
import os
import win32file
import win32con
ACTIONS = {
1 : "Created",
2 : "Deleted",
3 : "Updated",
4 : "Renamed from something",
5 : "Renamed to something"
}
# Thanks to Claudio Grondi for the correct set of numbers
FILE_LIST_DIRECTORY = 0x0001
path_to_watch = "."
hDir = win32file.CreateFile (
path_to_watch,
FILE_LIST_DIRECTORY,
win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE | win32con.FILE_SHARE_DELETE,
None,
win32con.OPEN_EXISTING,
win32con.FILE_FLAG_BACKUP_SEMANTICS,
None
)
while 1:
#
# ReadDirectoryChangesW takes a previously-created
# handle to a directory, a buffer size for results,
# a flag to indicate whether to watch subtrees and
# a filter of what changes to notify.
#
# NB Tim Juchcinski reports that he needed to up
# the buffer size to be sure of picking up all
# events when a large number of files were
# deleted at once.
#
results = win32file.ReadDirectoryChangesW (
hDir,
1024,
True,
win32con.FILE_NOTIFY_CHANGE_FILE_NAME |
win32con.FILE_NOTIFY_CHANGE_DIR_NAME |
win32con.FILE_NOTIFY_CHANGE_ATTRIBUTES |
win32con.FILE_NOTIFY_CHANGE_SIZE |
win32con.FILE_NOTIFY_CHANGE_LAST_WRITE |
win32con.FILE_NOTIFY_CHANGE_SECURITY,
None,
None
)
for action, file in results:
full_filename = os.path.join (path_to_watch, file)
print full_filename, ACTIONS.get (action, "Unknown")
一般来说,这个例子工作正常,做我想做的事。特别是,它在创建文件时工作正常。然而,当一个文件被编辑/修改/更新时,最后的打印语句(代表我真正想做的动作)会触发两次。
为什么会这样?以及如何防止它,或者至少解决它?我有过的最好的想法是第一次为 True 而第二次为 False 的标志。然而,这感觉就像一个杂牌。
关于一个可能相关的问题,我在哪里可以找到有关 win32con 包和 Microsoft ReadDirectoryChanges API 的文档?我做了一些谷歌搜索,但没有发现任何我认为有用的东西。
哦,是的 - 我在 Windows 7 Enterprise 上运行 Python 3.5.1。
编辑:好的,看起来我所看到的可能是 ReadDirectoryChangesW() 所固有的。我发现这个 StackOverflow 线程似乎基本上是相同的问题,除了原始海报使用的是 C++,而不是 Python。C++ WinApi:ReadDirectoryChangesW() 接收双重通知