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 <conio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include <string> #include "FileWatcher.h" #include <lua.h>
#include <lauxlib.h> 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);
windows下检測文件改变的更多相关文章
- windows下检測软件的网络连接
首先打开任务管理器选中你要查看的应用.右键转到进程 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZGFwZW5nMDExMg==/font/5a6L5L2 ...
- 用脚本如何实现将Linux下的txt文件批量转化为Windows下的txt文件?
众所周知,Windows和Linux的文件换行回车格式不同,Windows下换行格式是\r\n(回车+换行),Linux下换行格式为\n(只是换行),因此,其中一个操作系统的文本文件若需要在另外一个中 ...
- Windows 下目录及文件向Linux同步
本文解决的是Windows 下目录及文件向Linux同步的问题,Windows向 Windows同步的请参考:http://www.idcfree.com/article-852-1.html 环境介 ...
- Windows下如何将一个文件夹通过Git上传到GitHub上(转)
在通过windows系统的电脑上写代码,需要将项目上传到GitHub上去.比如在Pycharm上写Django后端,整个项目是一个文件夹的形式,那么怎么才能这个文件夹通过Git命令上传到GitHub上 ...
- windows下python检查文件是否被其它文件打开
windows下python检查文件是否被其它文件打开.md 有时候我们需要能够判断一个文件是否正在被其它文件访问,几乎不可避免的要调用操作系统接口 from ctypes import cdll i ...
- Linux&Windows下批量修改文件后缀
Linux下从给定文件夹中找出小于1M的文件,并批量添加.gif后缀 先看一下文件夹下的目录的格式 ll -Sh -rw-rw-r-- 1 yangkun yangkun 17M May 10 15: ...
- Windows下创建.gitgnore文件
相信使用过git的朋友可能遇到过,直接在windows下创建.gitgnore文件失败.类似截图那样 上网查了一下,有两种方法. 方法1: 此方法较为简单,前提是安装了git bash. 用git b ...
- windows下打开.ipynb文件
windows下打开.ipynb文件1.首先要下载python,设置环境变量2.下载pip,设置环境变量3.打开命令行,进入到python的Scripts文件中,按顺序执行下面三个命令pip inst ...
- Windows下C++遍历文件夹中的文件
Windows下,在VS中开发,C++遍历文件夹下文件. 在Windows下,遍历文件所用到的函数和结构体,需要在程序中包含头文件#include <io.h>,在VS中,头文件io.h实 ...
随机推荐
- 纵横填字js
新数据结构设计: 定义一个map: key是横纵坐标字符串,比如“0,4” value是一个json,包含以下属性:字,横向的词(若 有的话,无的话,空串),纵向的词(若有的话,无的话,空串). 另有 ...
- poj1240 Pre-Post-erous!
思路: 根据前序序列和后序序列递归构造m叉树,确定每个节点的子节点数量.再用组合数公式累乘. 实现: #include <iostream> using namespace std; ][ ...
- Angular——自定义服务
基本介绍 之前我们介绍了angular内置的几种服务,这里我们介绍如何自己定义自己的服务,主要是通过三个方法:factory.service.value 基本使用 factory:可以返回对象,也可以 ...
- react Native环境 搭建
react Native的优点:跨平台 低投入高回报 性能高 支持动态更新.一才两用(ios和Android) 开发成本第 代码复用率高.windows环境搭建react Native开发环境1.安装 ...
- 如何安装Ant,配置环境变量??
Apache Ant,是一个将软件编译.测试.部署等步骤联系在一起加以自动化的一个工具,大多用于Java环境中的软件开发. Ant是一个基于Java,并且主要用于Java工程的构建工具.Ant本意是A ...
- Spring框架系列(三)--Bean的作用域和生命周期
Bean的作用域 Spring应用中,对象实例都是在Container中,负责创建.装配.配置和管理生命周期(new到finalize()) Spring Container分为两种: 1.BeanF ...
- 计算机网络(二)--HTTP详解
Web相关内容都是存储在Web服务器上,Web服务器上使用的是http协议,因此也被成为http服务器.http的client.server构成了万维网的 基本组件 一.资源 1.URI: 统一资源标 ...
- oracle关闭
Alert log 要每天查看 abort 关闭冷备会无法使用
- 通过Oracle函数SQL实现C# String.Format字符串格式化功能
语言国际化要求,开发上要求Oracle数据库SQL中对应的返回信息-Message,实现一个通用函数调用,比如:提示信息内容:条码123456当前工站在FCT!”,即通用的信息内容格式化标准为:“条码 ...
- mybatis 使用参数
Parameter 1. 传入简单类型 JAVA代码: public User get(Long id) { return (User) getSqlSession().selectOne(&q ...