BOOL ReadDirectoryChangesW(
[in] HANDLE hDirectory,
[out] LPVOID lpBuffer,
[in] DWORD nBufferLength,
[in] BOOL bWatchSubtree,
[in] DWORD dwNotifyFilter,
[out, optional] LPDWORD lpBytesReturned,
[in, out, optional] LPOVERLAPPED lpOverlapped,
[in, optional] LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
[in] hDirectory
要监视的目录的句柄。 必须使用FILE_LIST_DIRECTORY访问权限打开此目录,或者具有包含FILE_LIST_DIRECTORY访问权限的GENERIC_READ等访问权限。
[out] lpBuffer
指向要返回读取结果的 DWORD 对齐格式缓冲区的指针。 此缓冲区的结构由 FILE_NOTIFY_INFORMATION 结构定义。 此缓冲区以同步方式或异步方式填充,具体取决于目录的打开方式以及向 lpOverlapped 参数提供的值。 有关详细信息,请参见“备注”部分。
[in] nBufferLength
lpBuffer 参数指向的缓冲区的大小(以字节为单位)。
[in] bWatchSubtree
如果此参数为 TRUE,函数将监视位于指定目录的目录树。 如果此参数为 FALSE,则函数仅监视 hDirectory 参数指定的目录。
[in] dwNotifyFilter
函数检查的筛选器条件,以确定等待操作是否已完成。 此参数可使用以下一个或多个值。
Value
FILE_NOTIFY_CHANGE_FILE_NAME
0x00000001
对受监视的目录或子树中文件名的任意更改都会导致返回一个更改通知等待操作。 更改包括重命名、创建或删除文件。
[out, optional] lpBytesReturned
对于同步调用,此参数接收传输到 lpBuffer 参数的字节数。 对于异步调用,此参数未定义。 必须使用异步通知技术检索传输的字节数。
[in, out, optional] lpOverlapped
指向在异步操作期间要使用的数据的 重叠 结构的指针。 否则,此值为 NULL。 不使用此结构的 Offset 和 OffsetHigh 成员。
[in, optional] lpCompletionRoutine
指向完成或取消操作并调用线程处于可警报等待状态时要调用的完成例程的指针。 有关此完成例程的详细信息,请参阅 FileIOCompletionRoutine。
如果该函数成功,则返回值为非零值。 对于同步调用,这意味着操作成功。 对于异步调用,这表示操作已成功排队。
如果函数失败,则返回值为零。 要获得更多的错误信息,请调用 GetLastError。
如果网络重定向程序或目标文件系统不支持此操作,该函数将失败 并ERROR_INVALID_FUNCTION。
若要获取目录句柄,请使用具有FILE_FLAG_BACKUP_SEMANTICS标志的 CreateFile 函数。
可以同步或异步完成对 ReadDirectoryChangesW 的调用。 若要指定异步完成,请使用 CreateFile 打开目录,如下所示,但另外在 dwFlagsAndAttributes 参数中指定FILE_FLAG_OVERLAPPED属性。 然后在调用 ReadDirectoryChangesW 时指定重叠结构。
首次调用 ReadDirectoryChangesW 时,系统会分配一个缓冲区来存储更改信息。 此缓冲区与目录句柄关联,直到关闭,其大小在其生存期内不会更改。 调用此函数时发生的目录更改将添加到缓冲区,然后使用下一次调用返回。 如果缓冲区溢出, ReadDirectoryChangesW 仍将返回 true,但会丢弃缓冲区的全部内容, lpBytesReturned 参数将为零,这表示缓冲区太小,无法保存发生的所有更改。
成功完成同步后, lpBuffer 参数是格式化缓冲区,写入缓冲区的字节数在 lpBytesReturned 中可用。 如果传输的字节数为零,则缓冲区太大,系统无法分配或太小,无法提供有关目录或子树中发生的所有更改的详细信息。 在这种情况下,应通过枚举目录或子树来计算更改。
对于异步完成,可以通过以下三种方式之一接收通知:
使用 GetOverlappedResult 函数。 若要通过 GetOverlappedResult 接收通知,请不要在 lpCompletionRoutine 参数中指定完成例程。 请务必将 OVERLAPPED 结构的 hEvent 成员设置为唯一事件。
使用 GetQueuedCompletionStatus 函数。 若要通过 GetQueuedCompletionStatus 接收通知,请不要在 lpCompletionRoutine 中指定完成例程。 通过调用 CreateIoCompletionPort 函数将目录句柄 hDirectory 与完成端口相关联。
使用完成例程。 若要通过完成例程接收通知,请不要将目录与完成端口相关联。 在 lpCompletionRoutine 中指定完成例程。
每当线程处于可警报等待状态时操作已完成或取消时,将调用此例程。 系统不使用 OVERLAPPED 结构的 hEvent 成员,因此你可以自行使用它。
有关详细信息,请参阅 同步和异步 I/O。
当缓冲区长度大于 64 KB 且应用程序通过网络监视目录时,ReadDirectoryChangesW 失败,ERROR_INVALID_PARAMETER。 这是因为数据包大小限制与基础文件共享协议有关。
当缓冲区未在 DWORD 边界上对齐时,ReadDirectoryChangesW 失败,ERROR_NOACCESS。
当系统无法记录目录的所有更改时,ReadDirectoryChangesW 失败,ERROR_NOTIFY_ENUM_DIR。
在这种情况下,应通过枚举目录或子树来计算更改。
如果使用短名称打开文件,则可以接收短名称的更改通知。
在Windows 8和Windows Server 2012中,以下技术支持此函数。
服务器消息块 (SMB) 3.0 协议
SMB 3.0 透明故障转移 (TFO)
具有横向扩展文件共享的 SMB 3.0 (SO)
群集共享卷文件系统 (CsvFS)
弹性文件系统 (ReFS)
如果存在绑定到目录句柄的事务,则通知会遵循相应的事务隔离规则。