windows 文件监控 c++ 11及以上版本可用
在该版本上稍微改了一下https://blog.csdn.net/weixin_50964512/article/details/125002563
#include<iostream>
#include<string>
#include<Windows.h>
#include<list>
#include<locale>
using namespace std;class WatchFolder {HANDLE m_hFile; //进行监视的文件句柄char* m_buf; //保存文件信息更改的缓存区
public:struct FILE_INFO{std::wstring name;DWORD action;FILE_INFO(const wchar_t* fileName, DWORD act) {name = fileName;action = act;}};//可监视的属性enum {NOTIFY_FILE_NAME = FILE_NOTIFY_CHANGE_FILE_NAME, //监视文件名更改NOTIFY_DIR_NAME = FILE_NOTIFY_CHANGE_DIR_NAME, //监视目录名更改NOTIFY_ATTRIBUTES = FILE_NOTIFY_CHANGE_ATTRIBUTES, //监视文件属性更改NOTIFY_SIZE = FILE_NOTIFY_CHANGE_SIZE, //监视文件大小更改NOTIFY_LAST_WRITE = FILE_NOTIFY_CHANGE_LAST_WRITE, //监视文件最后写入时间更改NOTIFY_LAST_ACCESS = FILE_NOTIFY_CHANGE_LAST_ACCESS, //监视文件最后访问时间更改NOTIFY_CREATION = FILE_NOTIFY_CHANGE_CREATION, //监视文件创建NOTIFY_SECURITY = FILE_NOTIFY_CHANGE_SECURITY, //监视文件安全描述符更改NOTIFY_ALL = NOTIFY_DIR_NAME|NOTIFY_FILE_NAME|NOTIFY_SIZE| NOTIFY_LAST_WRITE| NOTIFY_LAST_ACCESS| NOTIFY_CREATION| NOTIFY_ATTRIBUTES| NOTIFY_SECURITY //监视所有情况};//发生的行为enum {ACTION_ADD = FILE_ACTION_ADDED, //文件添加ACTION_REMOVE = FILE_ACTION_REMOVED, //文件删除ACTION_MODIFIED = FILE_ACTION_MODIFIED, //文件更改ACTION_RENAME_OLD=FILE_ACTION_RENAMED_OLD_NAME, //文件重命名(旧名字)ACTION_RENAME_NEW=FILE_ACTION_RENAMED_NEW_NAME //文件重命名(新名字)};
public:WatchFolder(int bufSize=4096) {m_hFile = nullptr;m_buf = new char[bufSize];}~WatchFolder(){Close();delete[] m_buf;}/*** @brief 初始化要进行监视的文件* @param dir * @return */bool Init(const std::wstring& dir) {if (m_hFile != nullptr) {CloseHandle(m_hFile);m_hFile = nullptr;}//打开文件m_hFile = CreateFileW(dir.data(), FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE| FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);return m_hFile != nullptr;}/*** @brief 关闭打开的文件句柄*/void Close() {if(m_hFile!=nullptr) CloseHandle(m_hFile);}/*** @brief 开始监视文件夹* @param fileInfo 返回发生改变的文件信息* @param filter 要进行监视的文件行为,可使用WatchFolder::NOTIFY_** @param IsWatchSubTree 是否监视子目录* @return 存在文件更改信息返回true,否则返回false*/bool BeginMonitor(std::list<FILE_INFO>& fileInfo, DWORD filter, bool IsWatchSubTree = false) {fileInfo.clear(); //清空列表DWORD lbyte; //得到返回的字节数BOOL ret = ReadDirectoryChangesW(m_hFile, m_buf, 4096, IsWatchSubTree, filter, &lbyte, NULL, NULL); //阻塞监视if (!ret ) return false; //失败FILE_NOTIFY_INFORMATION* event;DWORD offset = 0;//进入循环,解析所有信息do {event= (FILE_NOTIFY_INFORMATION*)(m_buf+offset); //得到FILE_NOTIFY_INFORMATION结构体,进行解析= (FILE_NOTIFY_INFORMATION*)m_buf; //得到FILE_NOTIFY_INFORMATION结构体,进行解析DWORD action=event->Action;wchar_t* fileName = new wchar_t[event->FileNameLength] {};memcpy(fileName, event->FileName, event->FileNameLength);fileInfo.push_back({ fileName,action});delete[] fileName;offset += event->NextEntryOffset;} while (event->NextEntryOffset!=0);delete event;memset(m_buf, 0, lbyte); //清空缓存区return !fileInfo.empty();}
};int main() {setlocale(LC_ALL, "");WatchFolder fol;bool ret = fol.Init(L"D:\\");if (!ret) {cout << "初始化失败";return -1;}list<WatchFolder::FILE_INFO> res;while (fol.BeginMonitor(res, WatchFolder::NOTIFY_ALL, true)) {for (auto& i : res) {switch (i.action){case WatchFolder::ACTION_ADD:wcout << i.name << L":\t文件被添加" << endl;break;case WatchFolder::ACTION_REMOVE:wcout << i.name << L":\t文件被删除" << endl;break;case WatchFolder::ACTION_MODIFIED:wcout << i.name << L":\t文件被更改" << endl;break;case WatchFolder::ACTION_RENAME_OLD:wcout << i.name << L":\t文件重命名" << endl;break;case WatchFolder::ACTION_RENAME_NEW:wcout << i.name << L":\t文件新名字" << endl;break;default:break;}}}
}