C++监视文件夹

来源:互联网 发布:淘宝男装店推荐 知乎 编辑:程序博客网 时间:2024/06/02 15:58
来自:http://topic.csdn.net/u/20080423/15/88f816e0-20ae-4628-b2f9-26f37c7aabc7.html以及http://blog.csdn.net/vbbianchengde/article/details/6914402
 
首先介绍几个重要的api函数:
  FindFirstChangeNotification( );
  FindNextChangeNotification( );
  WaitForSingleObject( );
  其中FindFirstChangeNotification(lpzpath,fwatchsubtree,fdwfilter)中的lpzpath表示要监视的路径名,fwatchsubtree判断是否查看子目录,fdwfilter为要监视的事件,函数执行成功后返回一个句柄。
  参数fdwfilter取值及其含义如下:
  FILE_NOTIFY_CHANGE_FILE_NAME  查看指定目录下任何文件名的改变
  FILE_NOTIFY_CHANGE_DIR_NAME  查看指定目录下任何目录名的改变
  FILE_NOTIFY_CHANGE_SIZE  查看指定目录下文件大小的改变
  FILE_NOTIFY_CHANGE_ATTRIBUTES  查看指定目录下文件属性的改变
  FindNextChangeNotification(hchange),hchange为FindFirstChangenNotification返回的句柄,其作用是请求系统
在下次检测到相应改变时发出改变通知消息句柄。当函数成功返回后,应用程序可通过WaitForMultipleObjects或WaitfForSingleObject来等待发生改变的通知。WaitForSingleObject(hchange,dwmilliseconds)中hchange为FindFirstChangeNotification 返回的句柄,dwmilliseconds为等待时间值,指定等待完成需要的时间,单位为毫秒。该值为-1时表示时间无限长。最好在结束监视程序之前先用FindCloseChangeNotification(hchange)来关闭句柄。
  下面给出一个简单的实例,其功能就是监视c:\pwin98目录下是否有文件发生变化。一旦有重命名、创建或删除情况发生时,通过Edit控件给出提示。
  //
  ----------------
  #include
  #pragma hdrstop
  
  #include “Unit1.h”
  //----------------
  #pragma package(smart_init)
  #pragma resource “*.dfm”
  TForm1 *Form1;
  //-----------------
  __fastcall TForm1::TForm1(Tcomponent* Owner)
   : Tform(Owner)
  {
  }
  //-------------------
  
  void __fastcall TForm1::FormCreate(Tobject *Sender)
  {
  DWORD dwWaitStatus;
  HANDLE dwChangeHandle; //返回通知的句柄
  dwChangeHandle=FindFirstChangeNotification(
  “C:\\PWIN98”,false,FILE_NOTIFY_CHANGE_FILE_NAME); //设置返回通知的句柄
  if(dwChangeHandle==INVALID_HANDLE_VALUE)
  //判断是否设置成功
   ExitProcess(GetLastError( ));
  while(true){ //设置循环,监视是否有
  dwWaitStatus=WaitForSingleObject(dwChangeHandle,-1); //通知返回
  switch(dwWaitStatus){
  case 0:
  Edit1->Text=“Something Changed”; //给出提示
  FindCloseChangeNotification(dwcChangeHandle); //关闭句柄
  exit(EXIT_SUCCESS); //退出程序
  default:
  ExitProcess(GetLastError( ));
  }
  }
  }
  程序在C++Builder4/PWin98下通过,由于C++Builder语言很标准,所以很容易扩展到其他编程语言环境中去。
  此例说明如何监视硬盘中文件变化,对于注册表,则有函数RegNotifyChangeKeyValue( )可以实现类似功能,这里暂省略之。  

方法二

主要用ReadDirectoryChangesW函数。
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>

typedef struct parm
{
char dir[128];
HANDLE hDir;
} THREAD_PARAM;

DWORD WINAPI thread(LPVOID lParam)
{
THREAD_PARAM *Par=(THREAD_PARAM *)lParam;
char notify[1024];
FILE_NOTIFY_INFORMATION *pnotify=(FILE_NOTIFY_INFORMATION *)notify;
char AnsiChar[3];
wchar_t UnicodeChar[2];
DWORD cbBytes;
printf("Watch [%s] start.\n",Par->dir);
while(true)
{
if(ReadDirectoryChangesW(Par->hDir,
&notify,
sizeof(notify),
true,
FILE_NOTIFY_CHANGE_FILE_NAME|
FILE_NOTIFY_CHANGE_DIR_NAME|
FILE_NOTIFY_CHANGE_ATTRIBUTES|
FILE_NOTIFY_CHANGE_SIZE|
FILE_NOTIFY_CHANGE_LAST_WRITE|
FILE_NOTIFY_CHANGE_LAST_ACCESS|
FILE_NOTIFY_CHANGE_CREATION|
FILE_NOTIFY_CHANGE_SECURITY,
&cbBytes,
NULL,
NULL))
{
switch(pnotify->Action)
{
case FILE_ACTION_ADDED:
printf("Directory/File added - ");
break;
case FILE_ACTION_REMOVED:
printf("Directory/File removed - ");
break;
case FILE_ACTION_MODIFIED:
printf("Directory/File modified - ");
break;
case FILE_ACTION_RENAMED_OLD_NAME:
printf("Directory/File old name - ");
break;
case FILE_ACTION_RENAMED_NEW_NAME:
printf("Directory/File new name - ");
break;
}
printf("%s/",Par->dir);
for(DWORD i=0;i<pnotify->FileNameLength/2;i++)
{
UnicodeChar[0]=pnotify->FileName[i];
UnicodeChar[1]=0;
ZeroMemory(AnsiChar,3);
WideCharToMultiByte(CP_ACP,0,UnicodeChar,-1,AnsiChar,3,NULL,NULL);
printf("%s",AnsiChar);
}
printf("\n");
}
}


}

int main(int argc,char **argv)
{
DWORD ThreadId;
THREAD_PARAM Par;
HANDLE hThread;
if(argc!=2)
{
printf("DirWatch <Directory>\n");
return 0;
}
lstrcpyn(Par.dir,argv[1],127);
Par.hDir = CreateFile(
Par.dir, // pointer to the file name
FILE_LIST_DIRECTORY, // access (read/write) mode
FILE_SHARE_READ|FILE_SHARE_WRITE, // share mode
NULL, // security descriptor
OPEN_EXISTING, // how to create
FILE_FLAG_BACKUP_SEMANTICS, // file attributes
NULL // file with attributes to copy
);

if(Par.hDir== INVALID_HANDLE_VALUE)
{
printf("Open Directory[%s] fail.\n",Par.dir);
return 0;
}


if(Par.hDir)
{
printf("Open Directory [%s] successfully.\n",Par.dir);

}
else
{
printf("Open Directory [%s] failed.\n",Par.dir);
return 0;
}
hThread=CreateThread(NULL,0,thread,(LPVOID *)&Par,0,&ThreadId);
if(hThread)
{
printf("CreateThread OK.\n");
printf("Press <q> to quit.\n");
while(getch()!='q');
TerminateThread(hThread,0);
WaitForSingleObject(hThread,1000);
CloseHandle(Par.hDir);
}
else
{
CloseHandle(Par.hDir);
printf("CreateThread failed, the program exit.\n");
}

}


原创粉丝点击