我一直试图让ReadDirectoryChangesW监视文件更改的子树,但我发现我得到不一致的结果。 以下是一个自包含的testing案例,说明了这个问题。 当我运行它有时会产生:
A : Created C : Updated A : Deleted
另一次可能会产生:
A : Created B : Updated C : Updated A : Deleted
我创build了一个巨大的缓冲区,正在更改的文件数量非常小(3个文件)。
代码:
import os, sys, time, threading import win32file, win32event, win32con, pywintypes class ChangeFiles ( threading.Thread ) : def run( self ) : files = [ 'A', 'B', 'C' ] time.sleep( 1 ) for path in files : f = open( path, 'w' ); f.write( 'mooo' ); f.close() time.sleep( 0.5 ) for path in files : os.remove( path ) ChangeFiles().start() FILE_LIST_DIRECTORY = 0x0001 handle = win32file.CreateFile ( '.', FILE_LIST_DIRECTORY, win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE | win32con.FILE_SHARE_DELETE, None, win32con.OPEN_EXISTING, win32con.FILE_FLAG_BACKUP_SEMANTICS | win32file.FILE_FLAG_OVERLAPPED, None ) buffer = win32file.AllocateReadBuffer( 1024 * 64 ) overlapped = pywintypes.OVERLAPPED() overlapped.hEvent = win32event.CreateEvent( None, 0, 0, None ) readFlags = 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 ACTIONS = { 1 : "Created", 2 : "Deleted", 3 : "Updated" } while 1 : win32file.ReadDirectoryChangesW( handle, buffer, False, readFlags, overlapped ) rc = win32event.WaitForSingleObject( overlapped.hEvent, 200 ) if rc == win32event.WAIT_OBJECT_0 : nbytes = win32file.GetOverlappedResult( handle, overlapped, True ) if nbytes > 0 : for action, file in win32file.FILE_NOTIFY_INFORMATION( buffer, nbytes ) : print '%s : %s' % ( file, ACTIONS.get ( action, "Unknown" ) ) else : print 'no bytes' break elif rc < 0 : print 'Error: %d' % win32api.GetLastError() break
这里的问题是你传递给WaitForSingleObject
的超时时间很短,所以在你得到有关事件的通知之前,函数往往会超时。 你的代码不检查这个条件,因此你看不到输出(也尝试测试rc > 0
)。
您可以通过将INFINITE
(即0xFFFFFFFF)的值传递给WaitForObject
来解决此WaitForObject
。