J'ai essayé d'obtenir ReadDirectoryChangesW pour surveiller un sous-arbre pour les changements de fichiers, mais j'ai constaté que je reçois des résultats incohérents. Ce qui suit est un cas de test autonome qui illustre le problème. Quand je lance ce qu'il produit parfois:ReadDirectoryChangesW semble manquer des événements
A : Created
C : Updated
A : Deleted
Une autre fois, il pourrait produire:
A : Created
B : Updated
C : Updated
A : Deleted
créer un tampon énorme, et le nombre de fichiers en cours de modification est très faible (3 fichiers).
Le code:
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
Je commence à deviner que c'est une situation où, si un arbre tombe dans la forêt et qu'il n'y a personne autour pour l'entendre, est-ce qu'il fait encore un bruit? Dans ce cas, s'il n'y a pas d'appel en attente à ReadDirectoryChangesW, et qu'une modification est apportée au système de fichiers, en apprendrez-vous plus long sur le changement? Peut-être pas. J'ai utilisé une bibliothèque python appelée watchdog qui semble fonctionner pour moi, mais j'aimerais quand même savoir pourquoi mon exemple de code ci-dessus manque des événements. –
Selon la [documentation] (http://msdn.microsoft.com/en-us/library/windows/desktop/aa365465%28v=vs.85%29.aspx), les modifications _Directory qui se produisent entre les appels à cette fonction sont ajoutés au tampon, puis renvoyés avec l'appel suivant. Les événements doivent donc être mis en mémoire tampon jusqu'à votre prochain appel. Je n'ai jamais utilisé python, mais je n'ai eu aucun problème avec cette API en code natif. – Luke