windows下检測文件改变

网友投稿 852 2022-09-19

windows下检測文件改变

windows下检測文件改变

这个主要是应用在我前一篇博客里提到的脚本热载入功能。 主要实现的功能检測目录内文件的变化(改变、新增、删除、重命名),当发现改变的时候通知lua又一次载入脚本。基本上就是一个windows api的使用。实际应用中会有一些细节须要注意,比方我习惯使用sublime text编辑。而sublime text保存文件不是直接改变文件内容,而是新增一个文件。这些细节情况须要实际使用中微调。         代码例如以下:   #include "FileWatcher.h" #include "cocos2d.h" #include "CCLuaEngine.h" using namespace cocos2d; #ifdef WIN32 // 函数: WatchChanges(LPVOID lpParameter) // // 目的: 监控文件夹的程序 // // 凝视:主函数创建线程时制定了这个函数的入口 // 届时该子程序将自己主动启动运行。 // 备注:由于代码不全,看以下的代码时,主要參考红色的字体部分 static int lastChangeTime = 0; void reloadGame() { int time = GetTickCount(); if (time - lastChangeTime <= 1000) { // 忽略短时间内的又一次载入请求 return; } Director::getInstance()->getScheduler()->performFunctionInCocosThread([](){ auto engine = LuaEngine::getInstance(); ScriptEngineManager::getInstance()->setScriptEngine(engine); lua_State* L = engine->getLuaStack()->getLuaState(); lua_getglobal(L, "reloadGame"); lua_call(L, 0, 0); }); } DWORD WINAPI WatchChanges(LPVOID lpParameter)//返回版本号信息 { wchar_t watchDirectory[512] = {0}; MultiByteToWideChar(CP_ACP, 0, (char*)lpParameter, strlen((char*)lpParameter), watchDirectory, sizeof(watchDirectory) / sizeof(wchar_t)); //创建一个文件夹句柄 HANDLE handle_directory=CreateFile(watchDirectory, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); if(handle_directory==INVALID_HANDLE_VALUE) { DWORD ERROR_DIR=GetLastError(); CCLOG("Open Directory Error"); } BOOL watch_state; while (TRUE) { char buffer[1024] = {0}; DWORD bytesReturned = 0; FILE_NOTIFY_INFORMATION* notify = (FILE_NOTIFY_INFORMATION*)buffer; watch_state=ReadDirectoryChangesW(handle_directory, (LPVOID)buffer, sizeof(buffer), TRUE, FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME|FILE_NOTIFY_CHANGE_LAST_WRITE, (LPDWORD)&bytesReturned, NULL, NULL); int err = GetLastError(); if (err == ERROR_INVALID_FUNCTION || err == ERROR_NOTIFY_ENUM_DIR) { return -1; } if(watch_state != 0) { DWORD length=WideCharToMultiByte(0,0,notify->FileName,-1,NULL,0,NULL,NULL); char fileName[256] = {0}; WideCharToMultiByte(0,0,notify->FileName,-1,fileName,length,NULL,NULL); //这里主要就是检測返回的信息,须要注意FILE_NOTIFY_INFORMATION结构体的定义,以便正确调用返回信息 if (notify->Action==FILE_ACTION_ADDED) { CCLOG("file add: %s", fileName); // sublime 改动文件是新增一个暂时文件,这个是兼容措施 reloadGame(); } if (notify->Action==FILE_ACTION_REMOVED) { CCLOG("file delete: %s", fileName); } if (notify->Action==FILE_ACTION_MODIFIED) { CCLOG("file changed: %s", fileName); reloadGame(); } //对于以下两种情况。Action本身也是文件名称(可能是old_name也可能是new_name) if (notify->Action==FILE_ACTION_RENAMED_OLD_NAME) { CCLOG("file rename old name: %s", fileName); } if (notify->Action==FILE_ACTION_RENAMED_NEW_NAME) { CCLOG("file rename new name: %s", fileName); } } Sleep(500); } return 0; } #endif void startWatch(const char* path) { #ifdef WIN32 static std::string s_path = path; //创建一个线程专门用于监控文件变化 HANDLE TrheadWatch=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)WatchChanges,(void*)s_path.c_str(),0,NULL); CloseHandle(TrheadWatch); #endif } 注冊给lua的实现:     #include "lua_cutil.h" //#include #include #include #include #include #include "FileWatcher.h" #include #include int lua_cutil_watch(lua_State *pL) { std::string path = luaL_checkstring(pL, 1); startWatch(path.c_str()); return 0; } int luaopen_cutil(lua_State *pL) { // 注冊lua函数 luaL_Reg reg [] = { {"watch", lua_cutil_watch}, {NULL, NULL} }; luaL_register(pL, "cutil", reg); return 1; } lua中调用的方式:     local mainPath = cc.FileUtils:getInstance():fullPathForFilename('Main.lua'); mainPath = string.sub(mainPath, 1, string.find(mainPath, 'Main%.lua') - 1); print(mainPath); cutil.watch(mainPath);

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:编译WINDOWS版FFmpeg:msys2环境准备
下一篇:分类与监督学习,朴素贝叶斯分类算法(带你理解朴素贝叶斯分类算法)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~