cocos2dx增加window的文件监控功能

一、目的

​ cocos2dx-lua游戏开发过程中能够监控某个文件夹下的文件变化。

二、实现window平台监控文件变化

FileWatch.h

#ifndef __FILE_WATCH_H__
#define __FILE_WATCH_H__

#include <vector>
#include <string>
#include <iostream>

#include "platform/CCPlatformConfig.h"

using namespace std;

class FileWatch
{
public:
	/*
		file notify struct
		action // it is a flag same as FILE_NOTIFY_INFORMATION's action
		old_name // old file name
		new_name // it has value only when the action is FILE_ACTION_RENAMED_OLD_NAME
	*/
	struct FileNotify
	{
		int action;
		std::string old_name;
		std::string new_name;
	};

	/*
		define struct for transfer params to thread
	*/
	struct FileWatchThreadParam
	{
		std::string *watch_dir; // watch_dir
		std::vector<FileWatch::FileNotify> *container; // file_name vector
	};

	virtual ~FileWatch();
	// single instance
	static FileWatch *getInstance();

	// create thread to monitor the dir
	void createFileWatchThread(std::string watchDir);

	// close monitor thread
	void closeFileWatchThread();

	std::vector<FileWatch::FileNotify> getChangeFileArray();

	std::string getWatchDir();
protected:
	FileWatch();
private:
	static FileWatch *_instance;
	FileWatchThreadParam _fwtp;
	// all notification
	std::vector<FileWatch::FileNotify> file_name;
	// monitor dir
	std::string watch_dir;
};

#endif  // __FILE_WATCH_H__


FileWatch.cpp

#include <windows.h>
#include <tchar.h>
#include "FileWatch.h"

FileWatch *FileWatch::_instance = nullptr;

#if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
// monitor thread
HANDLE hThread;
LPDWORD  threadId;
HANDLE dirHandle;
#endif

FileWatch::FileWatch()
{
}

FileWatch::~FileWatch()
{
	if (_instance == nullptr)
		return;
	delete _instance;
	_instance = nullptr;
}

FileWatch *FileWatch::getInstance()
{
	if (!_instance)
	{
		_instance = new FileWatch();
	}
	return _instance;
}

string WString2String(wstring wstr)
{
	string result;
	int len = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), wstr.size(), NULL, 0, NULL, NULL);
	char* buffer = new char[len + 1];
	WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, buffer, len + 1, NULL, NULL);
	//buffer[len] = '\0';
	result.append(buffer);
	delete[] buffer;
	return result;
}

LPCWSTR stringToLPCWSTR(std::string orig)
{
	size_t origsize = orig.length() + 1;
	const size_t newsize = 100;
	size_t convertedChars = 0;
	wchar_t *wcstring = (wchar_t *)malloc(sizeof(wchar_t)*(orig.length() - 1));
	mbstowcs_s(&convertedChars, wcstring, origsize, orig.c_str(), _TRUNCATE);

	return wcstring;
}

void _fileWatcher(std::string *dir, vector<FileWatch::FileNotify> *fn)
{
	DWORD cbBytes;
	char notify[1024] = "";
	dirHandle = CreateFile(stringToLPCWSTR(*dir), GENERIC_READ | GENERIC_WRITE | FILE_LIST_DIRECTORY,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		NULL,
		OPEN_EXISTING,
		FILE_FLAG_BACKUP_SEMANTICS,
		NULL);

	if (dirHandle == INVALID_HANDLE_VALUE)
	{
		printf("[FileWatch] CreateFile error:" + GetLastError());
		return;
	}

	FILE_NOTIFY_INFORMATION *pNotification = (FILE_NOTIFY_INFORMATION *)notify;

	BOOL watch_state;

	while (true)
	{
		watch_state = ReadDirectoryChangesW(dirHandle, &notify, 1024, true,
			//FILE_NOTIFY_CHANGE_FILE_NAME 
			FILE_NOTIFY_CHANGE_DIR_NAME
			| FILE_ACTION_RENAMED_OLD_NAME
			| FILE_ACTION_RENAMED_NEW_NAME
			//| FILE_NOTIFY_CHANGE_CREATION
			//| FILE_NOTIFY_CHANGE_LAST_WRITE
			| FILE_NOTIFY_CHANGE_SIZE,
			&cbBytes, NULL, NULL);

		if (watch_state == FALSE)
		{
			printf("[FileWatch] file watch error!");
			break;
		}
		else if (GetLastError() == ERROR_INVALID_FUNCTION)
		{
			printf("[FileWatch] system not support");
			break;
		}
		else if (GetLastError() == ERROR_NOTIFY_ENUM_DIR)
		{
			printf("[FileWatch] out of memory");
			break;
		}
		else {
			std::wstring szFileName = pNotification->FileName;
			FileWatch::FileNotify notifyStruct;
			notifyStruct.action = pNotification->Action;
			notifyStruct.old_name = "";
			notifyStruct.old_name = WString2String(szFileName);
			if (pNotification->Action == FILE_ACTION_RENAMED_OLD_NAME) {
				// get new file name
				WCHAR newName[1024] 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值