我正在尝试使用ReadDirectoryChangesW API在python上观看用于创建/删除/重命名更改的目录。这是我的代码,它运行正常:
results = win32file.ReadDirectoryChangesW(self.hDir, 8192, True, self.type, None,
None)
for action, file in results:
full_filename = os.path.join (self.source_path, file)
if action == 1: # Created
self.fileCreated(full_filename)
elif action == 2: # Deleted
self.fileDeleted(full_filename)
elif action == 3: # Updated
self.fileUpdated(full_filename)
elif action == 4: # Renamed from something
renamed_file = full_filename
elif action == 5: # Renamed to something
self.fileRenamed(renamed_file, full_filename)
但是,当我尝试从python或Windows资源管理器中删除监视文件夹时,我得到:
WindowsError:[错误32]进程无法访问该文件,因为它正由另一个进程使用:'c:\ users \ user \ appdata \ local \ temp \ new_dir'
我相信这是有道理的,但我该如何解决这个问题呢?因为我的应用程序应该允许用户删除监视文件夹。我尝试了异步方法http://www.themacaque.com/?p=859的解决方案,但它没有帮助。
提前致谢!
答案 0 :(得分:3)
[ReadDirectoryChangesW]的另一个潜在缺陷是引用的目录本身现在“正在使用”,因此无法删除。要监视目录中的文件并仍然允许删除目录,您必须监视父目录及其子目录。
该帖子还提供了有关正确使用ReadDirectoryChangesW
的更多详细信息答案 1 :(得分:2)
在ReadDirectoryChangesW
"Understanding ReadDirectoryChangesW - Part 2" by Jim Beveridge(正如Artomegus所提到的)是解决此问题的非常好的背景,但解释FILE_SHARE_DELETE
用法的说法具有误导性。
我的测试,使用FILE_SHARE_DELETE
实际上允许删除/重命名监视文件夹。 (换句话说,您不需要“观看父文件夹”作为唯一选项。)
以下是工作代码段(从这个非常优秀的"Watch a Directory for Changes" by Tim Golden
中大量编辑和借用# License is same as snippets on this page
# http://timgolden.me.uk/python/win32_how_do_i/watch_directory_for_changes.html
# In other words, bug Tim Golden to publish a license for his snippets
def windows_watch_path(watched_path):
import win32file
import win32con
ACTIONS = {
1 : "Created",
2 : "Deleted",
3 : "Updated",
4 : "RenamedFrom",
5 : "RenamedTo"
}
# Thanks to Claudio Grondi for the correct set of numbers
FILE_LIST_DIRECTORY = 0x0001
try:
hDir = win32file.CreateFile (
watched_path
, 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
)
except:
# either it does not exist by this time, or some other issue... blah.
# we'll just say "it 'changed' from 'some other expected state'"
return [[watched_path, '', ACTIONS[2]]]
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
)
files_changed = []
for action, fn in results:
files_changed.append(
[
watched_path
, fn
, ACTIONS[action]
]
)
# print fullfn, ACTIONS.get(action, "Unknown")
return files_changed
答案 2 :(得分:0)
好的,这个问题并不容易解决......在我的案例中(http://www.themacaque.com/?p=859),我忽略了允许重命名或删除目录的事实。
允许用户重命名监视文件夹的操作方法是使用路径祖先上的ReadDirectoryChangesW根据您正在观看的路径监视和过滤事件。我已经实现了一种新的方式来执行使用twisted来执行事件的处理。有了这个解决方案,你可以在以下情况下观察祖先:
在Windows上的Ubuntu One代码中,我们一直在处理这个问题,我们已经实现了一个很好的解决方案,你可以看看。它遵循一点点linux上pyinotify的实现,它带有一个处理器,允许你用一个回调来挂钩一个对象,这些回调将根据扭曲的反应堆主循环中的事件进行调用。看看那段代码,它可能对你有帮助。
我迟到的任何问题都在我的博客或irc中知道(在#ubuntuone或#pyar的freenode中)我的昵称是mandel;)