admin管理员组文章数量:1566659
一、Windows提供了几种方式对文件和目录进行监控,包括:FindFirstChangeNotification、ReadDirectoryChangesW、变更日志(Change Journal)等。
(1)FindFirstChangeNotification函数,可以监控到目标目录及其子目录中所有文件的变化,但不能监控到具体是哪一个文件发生改变。
(2)ReadDirectoryChangesW 能监控到目标目录下某一文件发生改变,并且可以知道发生变化的是哪一个文件。
注意,FindFirstChangeNotification 和 ReadDirectoryChangesW 是互斥的,不能同时使用。
(3)变更日志(Change Journal)可以跟踪每一个变更的细节,即使你的软件没有运行。很帅的技术,但也相当难用。
二、ReadDirectoryChangesW定义说明
ReadDirectoryChangesW 是Windows提供一个API,用于读取文件夹的磁盘变更。该API很实用,目前市面上已知的所有运行在用户态同步应用,都绕不开这个接口。但正确使用该API相对来说比较复杂,该接口能真正考验一个Windows开发人员对线程、异步IO、可提醒IO、IO完成端口等知识的掌握情况,如果读者还不熟悉这些技术,请先补充一下相关背景知识。
感谢 jimbeveridge (Multithreading Applications in Win32的作者)的精彩文章Understanding ReadDirectoryChangesW,建议读者也去读一下。jimbeveridge使用了可提醒IO实现对文件夹的磁盘监控。为了更深入的了解该API,在jimbeveridge基础上,我提供另一种IO完成端口异步模型,实现对文件夹的磁盘监控。
相关代码请参考github, 代码未经过充分测试,仅提供参考。
API简介
其函数原型为:
BOOL WINAPI ReadDirectoryChangesW(
_In_ HANDLE hDirectory,
_Out_ LPVOID lpBuffer,
_In_ DWORD nBufferLength,
_In_ BOOL bWatchSubtree,
_In_ DWORD dwNotifyFilter,
_Out_opt_ LPDWORD lpBytesReturned,
_Inout_opt_ LPOVERLAPPED lpOverlapped,
_In_opt_ LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
函数各个参数说明可以参考MSDN,由于该函数提供了丰富的调用方式,包括同步和异步方式。异步方式可以采用以下三种方式获取完成通知:
- 在OVERLAPPED结构中的hEvent成员中设置一个事件句柄,使用GetOverlappedResult 获取完成结果。
- 使用可提醒IO, 在参数lpComletionRoutine指定一个回调函数。当ReadDirectoryChangesW异步请求完成时,驱动会将指定的回调函数(lpComletionRoutine)投递到调用线程的APC队列中。对可提醒IO,OVERLAPPED结构中的hEvent 字段操作系统并不使用,我们可以自己使用该值。
- 使用IO完成端口,通过GetQueuedComletionStatus获取完成结果。
同步方式比较简单,但不具可伸缩性,在实际应用中并不多。不同的异步方式也影响到线程模型的选择,所以如何正确使用该函数其实并不容易。
ReadDirectoryChangesW的第一参数是一个文件夹句柄,所以首先需要正确打开一个文件夹,接下来主要描述怎样正确使用可提醒IO和IO完成端口方式调用ReadDirectoryChangesW,最后再谈谈怎样得体地退出线程(也是最容易被忽略的点);
打开文件夹
打开一个文件夹使用CreateFile,函数
版权声明:本文标题:Windows监控文件夹中文件变化 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1726947381a1091248.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论