`

浅谈ReadDirectoryChangesW函数的作用和问题所在

    博客分类:
  • c++
阅读更多
转自:http://www.cnblogs.com/yimins/archive/2010/05/18/1738379.html


  这两天又研究了一下ReadDirectoryChangesW函数,下面大致的将研究所得的一些心得体会拿出来和大家分享一下。
  首先这个函数的作用,主要是用于监控某个目录下文件或目录的改动事件。那么究竟这个函数是怎么运作的呢,我打一个比较容易理解的比方给大家。
  我们的应用程序就好比是茫茫大海上一个小小的灯塔,灯塔上有一个观察员(只有一个哦,原因?VB天生的单线程!)ReadDirectoryChangesW函数就好比一副望远镜,观察员的任务有如下三项:
1、通过望远镜观察海上经过的船只(相当于调用主函数进行文件监视)
2、记录下相应的船只名称(处理和记录得到的文件名)
3、和用户聊天。(-_-!!!其实就是负责与用户界面交互)
  由此可见,我们可怜的观察员其实是分身乏术的,尤其是工作3是不能轻易中断的,一旦观察员停止与用户交互,用户第一个反应就是:什么破程序,又卡死了!!!
  有点扯远了,我们言归正传,除聊天之外观察员的正式工作就是盯着望远镜(调用ReadDirectoryChangesW),一旦看到船只经过,立即在纸上抄下船只的名称(记录下被改动的文件名)。这就是ReadDirectoryChangesW函数在同步模式下的工作过程。缺点有两个:1、观察员专心观察,无法和用户聊天。(主窗体失去响应)2、当观察员低下头记录名称的时候,有可能有个别船只会偷偷溜过去。(文件改动事件丢失)
  知道了原因那么解决方式也很简单了,首先我们必须用多线程,再请一个观察员,专门负责盯着望远镜,主线程则负责和用户聊聊天就好了。第二个问题我们采用另一种方法,当观察员见到船只经过的时候,并不进行记录工作,而只是简单的给整个船体拍张照片,然后交给主线程,主线程负责看着照片记录船只名称。因为记录名称的工作并不是非常消耗时间,所以可以在聊天的间隙进行。当然,这样还会带来另一个小小的问题,你的照相机有多少空间,毕竟照相比仅仅记录一个名字要浪费许多空间。
  最后,再解释另一个可能造成丢失事件的原因。由于每次经过的船可能不止一艘,可能会有小船躲在大船后面溜过去,不过这个其实不是问题,因为ReadDirectoryChangesW函数返回的是所有船只的信息,其实是一个链表结构,我们只要顺藤摸瓜将后面的船只也抓出来并进行记录即可。



代码例子:
       //监控主文件夹变化
       string dir = "d:\\test\\";
	HANDLE dwRootDirChangeHandle = CreateFileA( 
		dir.c_str(), /* pointer to the file name */
		FILE_LIST_DIRECTORY,                /* (this is important to be FILE_LIST_DIRECTORY!) access (read-write) mode */
		FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE,  /* (file share write is needed, or else user is not able to rename file while you hold it) share mode */
		NULL, /* security descriptor */
		OPEN_EXISTING, /* how to create */
		FILE_FLAG_BACKUP_SEMANTICS, /* file attributes */
		NULL /* file with attributes to copy */
		);
	if (dwRootDirChangeHandle == INVALID_HANDLE_VALUE)
	{
		printf("error: %d", GetLastError());
		return 0;
	}

	char notify[1024];
	memset(notify, 0, 1024);
	DWORD cbBytes; 
	FILE_NOTIFY_INFORMATION *pNotify=(FILE_NOTIFY_INFORMATION *)notify;
	char str1[MAX_PATH], str2[MAX_PATH];

	while ( XSleep(10) )
	{	
		if(ReadDirectoryChangesW(dwRootDirChangeHandle, &notify, sizeof(notify),
			FALSE, FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_DIR_NAME/*FILE_NOTIFY_CHANGE_LAST_WRITE*/, &cbBytes, NULL, NULL))
		{			
			int i = 0;
			memset(str1, 0, MAX_PATH);
			WideCharToMultiByte( CP_ACP,0,pNotify->FileName, pNotify->FileNameLength/2, str1,99,NULL,NULL );

			switch(pNotify->Action)
			{
			case FILE_ACTION_ADDED:
				printf("New Folder: %s\n", str1);
				break;
			case FILE_ACTION_MODIFIED:
				printf("The file was modified. This can be a change in the time stamp or attributes.\n");
				break;
			case FILE_ACTION_REMOVED:
				printf("The file was removed from the directory.\n");
				break;
			case FILE_ACTION_RENAMED_NEW_NAME:
				printf("The file was renamed and this is the new name.\n");
				break;
			case FILE_ACTION_RENAMED_OLD_NAME:
				printf("The file was renamed and this is the old name.\n");
				break;
			default:
				printf("Unknown command.\n");
			}		

// 			if( 0 != pNotify->NextEntryOffset  && (pNotify->FileNameLength > 0 && pNotify->FileNameLength < MAX_PATH))
// 			{
// 				PFILE_NOTIFY_INFORMATION p = (PFILE_NOTIFY_INFORMATION)((char*)pNotify+pNotify->NextEntryOffset);
// 				memset( str2, 0, sizeof(str2) );
// 				WideCharToMultiByte( CP_ACP,0,p->FileName,p->FileNameLength/2,str2,99,NULL,NULL );
// 				cout << str2 << endl;
// 			}
			
		}
	}
	::CloseHandle(dwRootDirChangeHandle);
分享到:
评论

相关推荐

    ReadDirectoryChangesW iocp 目录监控

    ReadDirectoryChangesW函数通过一个名为I/O完成端口(IOCP,Input/Output Completion Port)的机制来实现异步操作。IOCP是一种高度优化的多线程并发I/O模型,它可以将I/O操作与处理结果的回调分离开来,从而提高系统...

    利用ReadDirectoryChangesW加重叠IO完美解决目录监控

    将ReadDirectoryChangesW函数利用重叠IO技术单独封装成线程类,完美的实现了目录文件变更的监控(支持UNC路径监控),CPU和内存占用低,无数据丢失项,使用简单方便,可以自行修改扩展功能。代码简洁容易理解。

    完成端口+目录监控(ReadDirectoryChangesW)

    总结起来,完成端口和ReadDirectoryChangesW是Windows平台上构建高性能并发I/O和服务监控的关键技术。掌握这两者,可以帮助开发者设计出更加健壮和高效的系统,特别是在需要处理大量文件操作的场景下。通过深入理解...

    VC++文件监控之ReadDirectoryChangesW

    然后,使用CreateFile函数创建一个文件句柄,并将其传递给ReadDirectoryChangesW函数。ReadDirectoryChangesW函数将监控文件系统中的变化,并将变化信息写入到一个缓冲区中。 缓冲区的结构体为FILE_NOTIFY_...

    CDirectoryChangeWatcher-05-12-2002_Src.zip

    CDirectoryChangeWatcher是一个实用的工具,它利用Windows API中的ReadDirectoryChangesW函数来实现对指定目录的实时监控,能够高效地捕获文件或子文件夹的创建、删除、重命名等操作。本文将深入探讨...

    vc 目录监视 实时监视目录中发生的一切事件,监视~~~~~

    在Windows操作系统中,可以使用WinAPI(Windows应用程序接口)中的FindFirstChangeNotification和ReadDirectoryChangesW函数来实现目录监视。这两个函数是Windows系统提供的一对API,用于监听文件系统的变化。 ...

    VC中 ReadDirectoryChangesW实时监视文件操作简单实例

    在VC++编程环境中,利用Windows API函数`ReadDirectoryChangesW`可以实现对文件系统的实时监控,从而检测到文件或文件夹的各种操作,如创建、删除、重命名和修改等。这个功能在许多应用场景中非常有用,例如日志记录...

    CDirectoryChangeWatcher-ReadDirectoryChangesW全部打包

    CDirectoryChangeWatcher是针对这一需求而设计的一个C++类库,它封装了Windows API中的ReadDirectoryChangesW函数,使得开发者可以更方便地实现文件系统的监控。 ReadDirectoryChangesW是Windows API中用于监视目录...

    监视系统的目录和文件变化

    Windows API中有一个名为`ReadDirectoryChangesW`的函数,它可以用来监控指定目录的变化。这个函数允许我们注册一个回调函数,当目录中发生指定类型的事件时,系统会调用该回调函数。Delphi可以通过PInvoke技术来...

    易语言监视文件夹是否被改动.zip

    1. **导入API函数**:在易语言中,首先需要导入ReadDirectoryChangesW函数,定义其参数类型和返回值类型。例如: ```易语言 .定义 DLL 函数 ReadDirectoryChangesW, 长整型, "kernel32.dll", ...

    文件监控 c++

    综上所述,利用C++和ReadDirectoryChangesW函数,开发者可以在Windows环境下有效地监控文件系统的变化,这对于文件同步、日志记录、数据备份等应用场景非常有用。通过不断轮询或设置事件通知,程序可以实时响应文件...

    目录监控 ReadDirectoryChanges with IOCP(不能用,不要下)

    本文将深入探讨如何利用Windows API中的`ReadDirectoryChangesW`函数和IO完成端口(IOCP)技术来实现高效的目录监控。我们将主要关注标题和描述中提到的知识点,并结合提供的`DirWatcher.cpp`和`DirWatcher.h`文件来...

    易语言API函数目录监控

    2. **目录监控**:通过API函数中的`ReadDirectoryChangesW`或`FindFirstChangeNotification`等函数,可以监控指定目录下的文件和子目录的变化,如新建、删除、重命名和修改等事件。 3. **创建监视对象**:使用`...

    VC 写的文件监视器源代码.rar

    首先,我们需要了解Windows API中的FindFirstChangeNotification和ReadDirectoryChangesW函数。这两个函数是实现文件系统监控的关键。FindFirstChangeNotification函数用于初始化监视,设置监控类型(如FILE_NOTIFY_...

    精选_使用ReadDirecotryChangesW函数实现文件监控_源码打包

    下面我们将详细讲解ReadDirectoryChangesW的工作原理和使用方法: 1. **工作原理**:ReadDirectoryChangesW首先在目标目录上设置一个通知,然后将更改信息放入一个缓冲区。当有变化发生时,系统会在缓冲区中填充...

    API函数目录监控.zip易语言项目例子源码下载

    易语言是一种基于中文编程的计算机程序设计语言,其设计目标是让编程...通过这个项目,学习者不仅可以深入理解API函数的使用,还能提升在易语言环境下解决问题的能力,对于提升编程技能和项目实战经验有着显著的帮助。

    windows目录监视程序,监视对目录下文件的读写.zip

    目录监视的核心在于Windows API中的几个关键函数,如ReadDirectoryChangesW和FindFirstChangeNotification等。这些API允许程序实时跟踪指定目录内的变化,包括文件的创建、删除、重命名和属性修改等事件。...

    利用Windows的未公开函数SHChangeNotifyRegister实现文件目录操作即时监视程序,

    此外,除了`SHChangeNotifyRegister`,Windows还提供了其他文件系统监控机制,例如`ReadDirectoryChangesW`函数,它可以异步地监控文件系统更改,并且在.NET Framework中,有`FileSystemWatcher`类提供封装好的API,...

    实时监控目录和文件的变化

    在IT行业中,实时监控目录和文件的...在实际编程中,还需要考虑错误处理、内存管理以及性能优化等问题,以确保程序的稳定性和效率。通过这些技术,我们可以在Windows平台上构建出高效、可靠的文件系统监控解决方案。

Global site tag (gtag.js) - Google Analytics