Windows提供了几种方式对文件和目录进行监控,包括:FindFirstChangeNotification、ReadDirectoryChangesW、变更日志(Change Journal)等。 (1)FindFirstChangeNotification函数,可以监控到目标目录及其子目录中所有文件的变化,但不能监控到具体是哪一个文件发生改变。 (2)ReadDirectoryChangesW 能监控到目标目录下某一文件发生改变,并且可以知道发生变化的是哪一个文件。 注意,FindFirstChangeNotification 和 ReadDirectoryChangesW 是互斥的,不能同时使用。 (3)变更日志(Change Journal)可以跟踪每一个变更的细节,即使你的软件没有运行。很帅的技术,但也相当难用。 SHChangeNotifyRegister,可以监控通过Explorer操作的文件 https://www.cnblogs.com/pjl1119/articles/ReadDirectoryChanges.html
用到了ReadDirectoryChangesW
PWCHAR szWatchDirectory = _T("");
HANDLE hDirectory=CreateFile(_T(""),
GENERIC_READ | GENERIC_WRITE | FILE_LIST_DIRECTORY ,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
NULL);
if(INVALID_HANDLE_VALUE == hDirectory)
{
DWORD dwErr=GetLastError();
return 0;
}
char notify[1024];
memset(notify, 0, sizeof(notify));
FILE_NOTIFY_INFORMATION *pNotification=(FILE_NOTIFY_INFORMATION *)notify;
DWORD BytesReturned=0;
while (TRUE)
{
ZeroMemory(pNotification, sizeof(notify));
DWORD watch_state=ReadDirectoryChangesW(hDirectory,
¬ify,
sizeof(notify),
TRUE, //监控子目录
FILE_NOTIFY_CHANGE_LAST_WRITE , //FILE_NOTIFY_CHANGE_FILE_NAME |FILE_NOTIFY_CHANGE_DIR_NAME FILE_NOTIFY_CHANGE_CREATION FILE_NOTIFY_CHANGE_SIZE
(LPDWORD)&BytesReturned,
NULL,
NULL);
if (GetLastError()==ERROR_INVALID_FUNCTION)
{
break;
}
else if(watch_state == FALSE)
{
DWORD dwErr = GetLastError();
break;
}
else if (GetLastError()==ERROR_NOTIFY_ENUM_DIR)
{
continue;
}
else
{
//这里主要就是检测返回的信息,(FILE_NOTIFY_INFORMATION)
std::wstring szFileName(pNotification->FileName,
pNotification->FileName + pNotification->FileNameLength/sizeof(WCHAR));
if (pNotification->Action==FILE_ACTION_ADDED)
{
printf("文件监控,新增文件! %S\\%S\n", szWatchDirectory, szFileName);
}
else if (pNotification->Action==FILE_ACTION_REMOVED)
{
printf("文件监控,删除文件! %S\\%S\n", szWatchDirectory, szFileName);
}
else if (pNotification->Action==FILE_ACTION_MODIFIED)
{
printf("文件监控,修改文件! %S\\%S\n", szWatchDirectory, szFileName);
}
else if (pNotification->Action==FILE_ACTION_RENAMED_OLD_NAME)
{
}
else if (pNotification->Action==FILE_ACTION_RENAMED_NEW_NAME)
{
}
}
}
CloseHandle(hDirectory);
下面的文章中有一个完整的例子
https://qualapps.blogspot.com/2010/05/understanding-readdirectorychangesw.html