ReadDirectoryChangesW()---同步模式监控目录中的文件

本文介绍了如何利用ReadDirectoryChangesW()函数在Windows系统中实现同步模式下对目录文件变化的监控,通过示例代码展示了具体实现过程。

直接上代码:

 

#include "stdafx.h"

typedef struct ThreadParameter   
{  
	LPTSTR in_directory;//监控的路径  
	FILE_NOTIFY_INFORMATION *in_out_notification;//存储监控函数返回信息地址  
	DWORD in_MemorySize;//传递存储返回信息的内存的字节数  
	DWORD *in_out_BytesReturned;//存储监控函数返回信息的字节数  
	FILE_NOTIFY_INFORMATION *temp_notification;//备用的一个参数  
}ThreadParameter; 

char* w2c(char *pcstr,const wchar_t *pwstr, size_t len)
{
	int nlength = wcslen(pwstr);
	int nbytes = WideCharToMultiByte(0,0,pwstr,nlength,NULL,0,NULL,NULL ); 

	// make sure the buffer is big enough for this, making it larger if necessary
	if(nbytes > len)   nbytes = len;

	// 通过以上得到的结果,转换unicode 字符为ascii 字符

	WideCharToMultiByte(0,0,pwstr,nlength,pcstr,nbytes,NULL,NULL);

	return pcstr ;
}

DWORD WINAPI WatchChanges(LPVOID lpParameter)
{ 
	ThreadParameter *parameter = (ThreadParameter*)lpParameter; 
	LPCTSTR WatchDirectory=parameter->in_directory;//监控目录 

	//创建一个目录句柄 
	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(); 
		MessageBox(NULL,TEXT("打开目录错误!"),TEXT("文件监控"),0); 
	} 

	BOOL watch_state;
	int dwNextEntryOffset(0);
	char szFileName[MAX_PATH] = {0};
	while(TRUE) 
	{ 
		watch_state = ReadDirectoryChangesW(handle_directory, 
			(LPVOID)parameter->in_out_notification, 
			parameter->in_MemorySize, 
			TRUE, 
			FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME|FILE_NOTIFY_CHANGE_LAST_WRITE, 
			(LPDWORD)parameter->in_out_BytesReturned, 
			NULL, 
			NULL); 

		//If the network redirector or the target file system does not support this operation, 
		//the function fails with ERROR_INVALID_FUNCTION.
		if (GetLastError() == ERROR_INVALID_FUNCTION) 
		{ 
			MessageBox(NULL,TEXT("系统不支持!"),TEXT("文件监控"),0); 
		} 
		//If the function fails, the return value is zero (0).
		else if(watch_state == 0)  
		{ 
			MessageBox(NULL,TEXT("监控失败!"),TEXT("文件监控"),0); 
		} 
		//If the buffer overflows, the changes are discarded and the function fails with ERROR_NOTIFY_ENUM_DIR.
		else if (GetLastError() == ERROR_NOTIFY_ENUM_DIR) 
		{ 
			MessageBox(NULL,TEXT("内存溢出!"),TEXT("文件监控"),0); 
		} 
		else 
		{ 
			do 
			{ 
				dwNextEntryOffset = parameter->in_out_notification->NextEntryOffset ; 

				switch (parameter->in_out_notification->Action) 
				{ 
					case FILE_ACTION_REMOVED : //文件删除        
						{ 
							w2c(szFileName,parameter->in_out_notification->FileName,sizeof(szFileName));
							printf("删除了一个文件:%s\n",szFileName);
						} 
						break ; 
					case FILE_ACTION_ADDED : //文件添加          
						{ 
							w2c(szFileName,parameter->in_out_notification->FileName,sizeof(szFileName));
							printf("添加了一个文件:%s\n",szFileName);
						} 
						break;
					case FILE_ACTION_MODIFIED :  //文件修改       
						{ 
							w2c(szFileName,parameter->in_out_notification->FileName,sizeof(szFileName));
							printf("修改了一个文件:%s\n",szFileName);
						} 
						break ; 
					case FILE_ACTION_RENAMED_OLD_NAME : //文件改名                     
						{
							w2c(szFileName,parameter->in_out_notification->FileName,sizeof(szFileName));
							printf("改名了一个文件:%s(OLD_NAME)\n",szFileName);
						}
						break;
					case FILE_ACTION_RENAMED_NEW_NAME: //文件改名:新名字
						{    
							w2c(szFileName,parameter->in_out_notification->FileName,sizeof(szFileName));
							printf("改名了一个文件:%s(NEW_NAME)\n",szFileName); 
						} 
						break ; 
					default:
						break;
				} 

				if (dwNextEntryOffset != 0) 
				{ 
					parameter->in_out_notification = (FILE_NOTIFY_INFORMATION*)((BYTE*)parameter->in_out_notification + dwNextEntryOffset); 
				} 

			}while(dwNextEntryOffset != 0); 

			memset(parameter->in_out_notification,'\0',1024); 
		}  
	} 
	return 0; 
} 

int _tmain(int argc, _TCHAR* argv[])
{
	char notify[1024] = {0}; 
	FILE_NOTIFY_INFORMATION *Notification = (FILE_NOTIFY_INFORMATION *)notify; 
	FILE_NOTIFY_INFORMATION *TempNotification = NULL; 
	DWORD BytesReturned = 0; 
	DWORD version = 0; 

	ThreadParameter ParameterToThread = {"D:\\Data",Notification,sizeof(notify),&BytesReturned,TempNotification}; 

	HANDLE TrheadWatch = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)WatchChanges,&ParameterToThread,0,NULL); 
	CloseHandle(TrheadWatch); 

	while (TRUE)
	{
		Sleep(10000);
	}
	return 0;
}


结果:

 

 

删除了一个文件:复件 微信000.lnk
改名了一个文件:微信000.lnk$.lnk(OLD_NAME)
改名了一个文件:微信0001.lnk.lnk(NEW_NAME)
添加了一个文件:新建 文本文档.txt
修改了一个文件:新建 文本文档.txt\
修改了一个文件:新建 文本文档.txt\

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小米的修行之路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值