热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

windows下检测文件改变

这个主要是应用在我前一篇博客里提到的脚本热加载功能。主要实现的功能检测文件夹内文件的变化(改变、新增、删除、重命名),当发现改变的时候通知lua重新加载脚本。基本上就是一个window

        这个主要是应用在我前一篇博客里提到的脚本热加载功能。主要实现的功能检测文件夹内文件的变化(改变、新增、删除、重命名),当发现改变的时候通知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);



推荐阅读
  • 主线:设计窗口类注册窗口类产生窗口显示窗口更新窗口消息循环(将消息路由到窗口中去处理)。APPMODUL.CPP源文件被编译链接进入项目,从APPMOD ... [详细]
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • pthread_mutex_lockpthread_mutex_lock(pthread_mutex_t*mutex);intpthread_mutex_trylock(pthre ... [详细]
  • 我首先提高本程序的权限,然后成功得到服务程序(exe)的读写权限,开辟新的远程内存空间,然后拷贝程序执行的代码,但写入我的dll后,服务程序什么反应也没有。 ... [详细]
  • 采用CreateThread()创建多线程程序
    本位转自:http:blog.csdn.netcbnotesarticledetails8277180在window环境下,Win32提供了一系列的AP ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 流数据流和IO流的使用及应用
    本文介绍了流数据流和IO流的基本概念和用法,包括输入流、输出流、字节流、字符流、缓冲区等。同时还介绍了异常处理和常用的流类,如FileReader、FileWriter、FileInputStream、FileOutputStream、OutputStreamWriter、InputStreamReader、BufferedReader、BufferedWriter等。此外,还介绍了系统流和标准流的使用。 ... [详细]
  • 本文介绍了使用C++Builder实现获取USB优盘序列号的方法,包括相关的代码和说明。通过该方法,可以获取指定盘符的USB优盘序列号,并将其存放在缓冲中。该方法可以在Windows系统中有效地获取USB优盘序列号,并且适用于C++Builder开发环境。 ... [详细]
  • Linux 中使用 clone 函数来创建线程
    2019独角兽企业重金招聘Python工程师标准Linux上创建线程一般使用的是pthread库实际上libc也给我们提供了创建线程的函数那就是cloneintclone(i ... [详细]
  • C语言编程gcc怎么生成静态库.a和动态库.so
    这篇文章将为大家详细讲解有关C语言编程gcc怎么生成静态库.a和动态库.so,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章 ... [详细]
  • burp爆破线程设置多少_Linux中的线程局部存储解析
    在Linux系统中使用CC进行多线程编程时,我们遇到最多的就是对同一变量的多线程读写问题,大多情况下遇到这类问题都是通过锁机制来处理,但这 ... [详细]
  • 本文讨论了如何使用GStreamer来删除H264格式视频文件中的中间部分,而不需要进行重编码。作者提出了使用gst_element_seek(...)函数来实现这个目标的思路,并提到遇到了一个解决不了的BUG。文章还列举了8个解决方案,希望能够得到更好的思路。 ... [详细]
  • 本文总结和分析了JDK核心源码(2)中lang包下的基础知识,包括常用的对象类型包和异常类型包。在对象类型包中,介绍了Object类、String类、StringBuilder类、StringBuffer类和基本元素的包装类。在异常类型包中,介绍了Throwable类、Error类型和Exception类型。这些基础知识对于理解和使用JDK核心源码具有重要意义。 ... [详细]
  • OpenMap教程4 – 图层概述
    本文介绍了OpenMap教程4中关于地图图层的内容,包括将ShapeLayer添加到MapBean中的方法,OpenMap支持的图层类型以及使用BufferedLayer创建图像的MapBean。此外,还介绍了Layer背景标志的作用和OMGraphicHandlerLayer的基础层类。 ... [详细]
author-avatar
忧郁王囝
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有