Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python ReadDirectoryChangesW似乎缺少事件_Python_Windows_Readdirectorychangesw - Fatal编程技术网

Python ReadDirectoryChangesW似乎缺少事件

Python ReadDirectoryChangesW似乎缺少事件,python,windows,readdirectorychangesw,Python,Windows,Readdirectorychangesw,我一直试图让ReadDirectoryChangesW监视子树中的文件更改,但我发现结果不一致。下面是一个自包含的测试用例,它说明了这个问题。当我运行此程序时,它有时会生成: A : Created C : Updated A : Deleted 另一次可能会产生: A : Created B : Updated C : Updated A : Deleted 我创建了一个巨大的缓冲区,被更改的文件数量非常少(3个文件) 守则: import os, sys, time, threading

我一直试图让ReadDirectoryChangesW监视子树中的文件更改,但我发现结果不一致。下面是一个自包含的测试用例,它说明了这个问题。当我运行此程序时,它有时会生成:

A : Created
C : Updated
A : Deleted
另一次可能会产生:

A : Created
B : Updated
C : Updated
A : Deleted
我创建了一个巨大的缓冲区,被更改的文件数量非常少(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
导入操作系统、系统、时间、线程
导入win32file、win32event、win32con、pywintypes
类ChangeFiles(threading.Thread):
def运行(自):
文件=['A','B','C']
时间。睡眠(1)
对于文件中的路径:f=open(路径“w”);f、 写('mooo');f、 关闭()
睡眠时间(0.5)
对于文件中的路径:os.remove(路径)
ChangeFiles().start()
文件列表目录=0x0001
handle=win32file.CreateFile(
'.',
文件列表目录,
win32con.FILE_SHARE_READ|win32con.FILE_SHARE_WRITE|win32con.FILE_SHARE_DELETE,
没有一个
win32con.OPEN_存在,
win32con.FILE_FLAG_BACKUP_语义| win32file.FILE_FLAG_重叠,
没有一个
)
buffer=win32file.allocateradbuffer(1024*64)
overlapped=pywintypes.overlapped()
overlapped.hEvent=win32event.CreateEvent(无,0,0,无)
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\u通知\u更改\u安全性
操作={1:“已创建”,2:“已删除”,3:“已更新”}
而1:
win32file.ReadDirectoryChangesW(句柄、缓冲区、False、readFlags、重叠)
rc=win32event.WaitForSingleObject(overlapped.hEvent,200)
如果rc==win32event.WAIT\u对象\u 0:
nbytes=win32file.GetOverlappedResult(句柄,重叠,True)
如果N字节>0:
要执行操作,请在win32file.file\u NOTIFY\u信息(缓冲区,N字节)中输入文件:
打印“%s:%s%”(文件,ACTIONS.get(操作,“未知”))
其他:
打印“无字节”
打破
elif rc<0:
打印错误:%d'%win32api.GetLastError()
打破

这里的问题是,您传递给
WaitForSingleObject
的超时非常低,因此函数往往会在收到事件通知之前超时。您的代码没有检查该条件,因此您看不到任何输出(也可以尝试测试
rc>0


您可以通过将
INFINITE
(即0xffffff)的值传递给
WaitForObject

来解决此问题。我开始猜测,如果一棵树倒在森林中,周围没有人听到它,它还会发出声音吗?在这种情况下,如果没有对ReadDirectoryChangesW的未决调用,并且文件系统发生了更改,您以后会了解该更改吗?也许不是。我一直在使用一个名为watchdog的python库,它似乎对我有用,但我仍然想知道为什么上面的代码示例遗漏了事件。根据,在调用此函数之间发生的目录更改被添加到缓冲区,然后在下次调用时返回。所以事件应该被缓冲,直到下一次调用。我从未使用过python,但在本机代码中使用该API时没有遇到任何问题。