当前位置: 首页 > article >正文

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;
			}
		}
	}
}

http://www.kler.cn/a/381042.html

相关文章:

  • springboot vue 会员营销系统
  • 项目代码第6讲:UpdownController.cs;理解 工艺/工序 流程、机台信息;前端的“历史 警报/工艺 记录”
  • 运维工程师面试系统监控与优化自动化与脚本云计算的理解虚拟化技术的优点和缺点
  • 全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(switch语句)
  • KingbaseES(金仓数据库)入门学习
  • 写作词汇积累:纰漏、坎肩、颠三倒四、隔阂
  • 接口测试(十一)jmeter——断言
  • 力扣最热一百题——验证二叉搜索树
  • 计算机存储单元bit。不同编程语言类型差异。
  • Python面向对象:类和对象的基本操作
  • 在gitlab,把新分支替换成master分支
  • LeetCode 3165.不包含相邻元素的子序列的最大和:单点修改的线段树(动态规划)
  • easyui +vue v-slot 注意事项
  • Grafana+Prometheus监控篇-Nginx
  • C#中,Thread和Task的区别
  • 人工智能基础-opencv-图像处理篇
  • 第二届新生程序设计竞赛热身赛(C语言)
  • File和InputStream,OutputStream
  • JavaEE初阶---网络原理值TCP篇(三)
  • gradle下载的jar包,源码出现Decompiled .class file, bytecode version
  • nginx监控指标有哪些
  • AI开发-三方库-torch-torchvision
  • Redis学习:BigKey、缓存双写一致性更新策略和案例
  • 小土堆学习笔记15:搭建小实战和Sequential的使用
  • w~自动驾驶~合集4
  • 【深度学习】DreamClear:提升图片分辨率的模型