本文测试了ReadDirectoryChangesW 类监控文件变化。
#include<iostream>
#include<string>
#include<Windows.h>
using namespace std;
string WStringToString(const std::wstring &wstr);
void RunWatchFile()
{
string watchDirectory = "E:/Test";
HANDLE hDirectory = CreateFile(watchDirectory.c_str(),
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 (hDirectory == INVALID_HANDLE_VALUE)
{
DWORD dwErr = GetLastError();
return;
}
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));
auto watchState = ReadDirectoryChangesW(hDirectory,
¬ify,
sizeof(notify),
TRUE, //监控子目录
FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE,
(LPDWORD)&bytesReturned,
NULL,
NULL);
if (GetLastError() == ERROR_INVALID_FUNCTION)
{
cout << "文件监控,系统不支持 " << watchDirectory << endl;
break;
}
else if (watchState == FALSE)
{
DWORD dwErr = GetLastError();
cout << "文件监控,监控失败 " << watchDirectory << dwErr << endl;
break;
}
else if (GetLastError() == ERROR_NOTIFY_ENUM_DIR)
{
cout << "文件监控,内存溢出 " << watchDirectory <<endl;
continue;
}
else
{
//检测返回的信息
wstring fileName(pNotification->FileName, pNotification->FileNameLength / sizeof(wchar_t));
std::string fullFileName = watchDirectory + "/" + WStringToString(fileName);
if (pNotification->Action == FILE_ACTION_ADDED)
{
cout << "文件监控,新增文件 " << fullFileName << endl;
}
else if (pNotification->Action == FILE_ACTION_REMOVED)
{
cout << "文件监控,删除文件 " << fullFileName << endl;
}
else if (pNotification->Action == FILE_ACTION_MODIFIED)
{
cout << "文件监控,修改文件 " << fullFileName << endl;
}
else if (pNotification->Action == FILE_ACTION_RENAMED_OLD_NAME)
{
cout << "文件监控,重命名文件 " << fullFileName << endl;
}
//PostMessage通知主线程
}
}
CloseHandle(hDirectory);
}
string WStringToString(const std::wstring &wstr)
{
string result;
//获取缓冲区大小,并申请空间,缓冲区大小事按字节计算的
int len = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), NULL, 0, NULL, NULL);
char* buffer = new char[len + 1];
//宽字节编码转换成多字节编码
WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), buffer, len, NULL, NULL);
buffer[len] = '\0';
//删除缓冲区并返回值
result.append(buffer);
delete[] buffer;
return result;
}
int main()
{
RunWatchFile();
getchar();
return 0;
}
上例中监控的目录是“E:\\Test”,在此目录下创建txt文件,命名为“log.txt”。
运行结果: