文件系统变化通知首先要明白一点什么是“文件系统变化”?其实也就是操作系统中一个磁盘的目录结构发生了变化,当你要监视这种变化时,在Win32下可以使用FindFirstChangeNotification函数,
HANDLE FindFirstChangeNotification(LPTSTR lpszPath,BOOL fWatchSubTree,DWORD fdwFilter);
参数说明:
lpszPath是你要监视的目录树的根。该参数可以为任何驱动器的根目录或是子目录。
fWatchSubTree是告诉系统你是否想查看lpszPath目录的下属目录中的事件。
FdwFilter是要查看的文件类型。它可以为下面这些值,
FILE_NOTIFY_CHANGE_FILE_NAME、FILE_NOTIFY_CHANGE_DIR_NAME、FILE_NOTIFY_CHANGE_ATTRIBUTES、FILE_NOTIFY_CHANGE_SIZE、FILE_NOTIFY_CHANGE_CREATION、FILE_NOTIFY_CHANGE_LAST_WRITE、FILE_NOTIFY_CHANGE_LAST_ACCESS、FILE_NOTIFY_CHANGE_SECURITY。
如果FindFirstChangeNotification调用成功,它将返回一个“文件变化通知对象”的句柄。如果在调用该函数时传递了一个无效参数,如一个不存在的目录,该函数就会返回INVALID_HANDLE_VALUE。例如:你的线程在执行删除一个文件的操作时,使用WaitForSingleObject来等待“文件变化通知对象”变成有信号状态,这时,你就可以使用FindFisrtChangeNotification函数来得到有关“文件变化通知对象”的句柄,来得到它的进一步信息,使用它来判断“文件变化通知对象”是否变成了有信号状态,如果是,那么你的线程就会被唤醒,来做其它操作了。
在调用完FindFirstChangeNotification后,要想继续对某个目录的变化进行监视,那么就要调用FindNextChangeNotification函数,该函数把“文件变化通知对象”变为无信号状态。
当你不再需要“文件变化通知对象”时,你必须使用函数FindCloseChangeNotification来关闭“文件变化通知对象”,
BOOL FindCloseChangeNotification(HANDLE hChange);
另一个比FindFirstChangeNotification函数更有效的函数:ReadDirectoryChangesW,
BOOL ReadDirectoryChangesW(HANDLE hDirectory,LPVOID lpBuffer,
DWORD nBufferLength,BOOL bWatchSubTree,
DWORD dwNotifyFilter,LPDWORD lpBytesReturned,
LPOVERLAPPED lpOverLapped,L
POVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
第一个参数是你通过CreateFile返回的句柄。
参数说明:
lpBuffer是一块指向结构FIND_NOTIFY_INFORMATION的地址。
监视程序,它的用途主要是在后台监视系统中关键信息的改变,比如注册表的改变及硬盘上由于文件操作引起的改变等等。下面我们开始讨论如何编程实现这一监视功能。首先介绍几个重要的api函数:
FindFirstChangeNotification( );
FindNextChangeNotification( );
WaitForSingleObject( );
其中FindFirstChangeNotification(lpzpath,fwatchsubtree,fdwfilter)中的lpzpath表示要监视的路径名,fwatchsubtree判断是否查看子目录,fdwfilter为要监视的事件,函数执行成功后返回一个句柄。
参数fdwfilter取值及其含义如下:
FILE_NOTIFY_CHANGE_FILE_NAME 查看指定目录下任何文件名的改变
FILE_NOTIFY_CHANGE_DIR_NAME 查看指定目录下任何目录名的改变
FILE_NOTIFY_CHANGE_SIZE 查看指定目录下文件大小的改变
FILE_NOTIFY_CHANGE_ATTRIBUTES 查看指定目录下文件属性的改变
FindNextChangeNotification(hchange),hchange为FindFirstChangenNotification返回的句柄,其作用是请求系统在下次检测到相应改变时发出改变通知消息句柄。当函数成功返回后,应用程序可通过WaitForMultipleObjects或WaitfForSingleObject来等待发生改变的通知。 WaitForSingleObject(hchange,dwmilliseconds)中hchange为FindFirstChangeNotification 返回的句柄,dwmilliseconds为等待时间值,指定等待完成需要的时间,单位为毫秒。该值为-1时表示时间无限长。最好在结束监视程序之前先用FindCloseChangeNotification(hchange)来关闭句柄。
下面给出一个简单的实例,其功能就是监视c:/pwin98目录下是否有文件发生变化。一旦有重命名、创建或删除情况发生时,通过Edit控件给出提示。
DWORD dwWaitStatus;
HANDLE dwChangeHandle; //返回通知的句柄
dwChangeHandle=FindFirstChangeNotification(
“C://PWIN98”,false,FILE_NOTIFY_CHANGE_FILE_NAME); //设置返回通知的句柄
if(dwChangeHandle==INVALID_HANDLE_VALUE)
//判断是否设置成功
ExitProcess(GetLastError());
while(true){ //设置循环,监视是否有
dwWaitStatus=WaitForSingleObject(dwChangeHandle,-1); //通知返回
if(dwWaitStatus==0){
MessageBox(NULL,"Notification",“Something Changed”,MB_OK); //给出提示
FindCloseChangeNotification(dwcChangeHandle); //关闭句柄
exit(EXIT_SUCCESS); //退出程序
}
}
此例说明如何监视硬盘中文件变化,对于注册表,则有函数RegNotifyChangeKeyValue()可以实现类似功能。