• 使用完成例程监控文件目录的例子


    由于项目需要实现了一个文件监控服务,期间研究过使用完成例程的方式来监控文件目录。

    下面简单的BCB6命令行实现版本。(参考来源 http://bbs.csdn.net/topics/340172813 )

    下次补充一个完成端口的版本。

      1 //---------------------------------------------------------------------------
      2 // 使用完成例程监控当前文件夹
      3 //------------------------------------------------------------------------------
      4 
      5 
      6 
      7 
      8 #include <vcl.h>
      9 #pragma hdrstop
     10 #include <iostream>
     11 using namespace std;
     12 
     13 
     14 //---------------------------------------------------------------------------
     15 
     16 #pragma argsused
     17 
     18 
     19 HANDLE hThreadHandle = NULL ;
     20 HANDLE hMonitorDirHandle = NULL;
     21 HANDLE hMonitorEventHandle = NULL;
     22 
     23 //这个回调函数,是完成例程的核心
     24 //在IO 完成的时候会触发。
     25 //然后这个回调函数去设置overlapped->hEvent信号量
     26 //使线程能不被阻塞。
     27 void CALLBACK FileIOCompletionRoutine(  DWORD dwErrorCode,
     28                                         DWORD dwNumberOfBytesTransfered,
     29                                         LPOVERLAPPED lpOverlapped)
     30 {
     31     if(dwErrorCode)
     32     {
     33         printf("Error Code:%d
    ",dwErrorCode);
     34     }
     35     //设置信号量,多线程会得到通知
     36     SetEvent(lpOverlapped->hEvent);
     37 }
     38 
     39 DWORD WINAPI MonitorThread( LPVOID )
     40 {
     41     OVERLAPPED overlapped={0};
     42     DWORD ByteReturn = 0;
     43     DWORD BufferLen=10*(sizeof(FILE_NOTIFY_INFORMATION)+MAX_PATH*sizeof(TCHAR));
     44     FILE_NOTIFY_INFORMATION* Buffer=
     45         (FILE_NOTIFY_INFORMATION*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,BufferLen);
     46 
     47     while(true)
     48     {
     49         //简单起见只监控了 修改文件和文件目录
     50         if(ReadDirectoryChangesW(hMonitorDirHandle,Buffer,BufferLen,TRUE,
     51             FILE_NOTIFY_CHANGE_DIR_NAME|FILE_NOTIFY_CHANGE_FILE_NAME,
     52             &ByteReturn,&overlapped,FileIOCompletionRoutine))
     53         {
     54             DWORD dwResult;
     55             //这个信号一开始没信号的,直到完成例程回调被调用(FileIOCompletionRoutine)
     56             dwResult=WaitForSingleObjectEx(hMonitorEventHandle,INFINITE,TRUE);
     57             if(dwResult==WAIT_IO_COMPLETION    )
     58             {
     59                 FILE_NOTIFY_INFORMATION* notify = Buffer;
     60 
     61                 AnsiString fileName =
     62                         WideCharLenToString(
     63                             notify->FileName,notify->FileNameLength/2);
     64                 do
     65                 {
     66                     bool blNormal = true;
     67                     switch(notify->Action)
     68                     {
     69                     case FILE_ACTION_ADDED:
     70                         {
     71                             cout<<"增加了文件"<<fileName.c_str()<<endl;
     72                         }
     73                         break;
     74                     case FILE_ACTION_REMOVED:
     75                         {
     76                             cout<<"删除了文件"<<fileName.c_str()<<endl;
     77                         }
     78                         break;
     79                     case FILE_ACTION_MODIFIED:
     80                         {
     81                             cout<<"修改了文件"<<fileName.c_str()<<endl;
     82                         }
     83                         break;
     84                     case FILE_ACTION_RENAMED_OLD_NAME:
     85                         {
     86                             cout<<"被重名的文件"<<fileName.c_str()<<endl;
     87                         }
     88                         break;
     89                     case FILE_ACTION_RENAMED_NEW_NAME:
     90                         {
     91                             cout<<"新命名的文件"<<fileName.c_str()<<endl;
     92                         }
     93                         break;
     94                     default:   //有可能已经溢出了!
     95                         blNormal = false;
     96                         break;
     97                     }
     98 
     99                     if(!blNormal)
    100                     {
    101                         break;
    102                     }
    103                     //将指针偏移offset个字节
    104                     notify =  notify + notify->NextEntryOffset;
    105                 }
    106                 while(notify->NextEntryOffset>0);
    107            }
    108            //重新设置信号量,继续阻塞
    109            ResetEvent(hMonitorEventHandle);
    110         }
    111         else
    112         {
    113             cout<<"缓冲溢出!"<<SysErrorMessage(GetLastError()).c_str()<<endl;
    114             break;
    115         }
    116     }
    117     HeapFree(GetProcessHeap(),0,Buffer);
    118     return 0;
    119 }
    120 
    121 int main(int argc, char* argv[])
    122 {
    123     AnsiString mointorDir = ExtractFileDir(Application->ExeName);
    124 
    125     hMonitorDirHandle=CreateFile(mointorDir.c_str(),
    126         FILE_LIST_DIRECTORY,                            //见MSDN ReadDirectoryChangesW 函数说明
    127         FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE,
    128         NULL,
    129         OPEN_EXISTING,
    130         FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED,//FILE_FLAG_OVERLAPPED表示异步模式,当异步的IO 完成的时,会填充OVERLAPPED结构
    131         NULL);
    132 
    133     if(hMonitorDirHandle == INVALID_HANDLE_VALUE)
    134     {
    135         cout<<"打开监控文件夹失败!"<< SysErrorMessage(GetLastError()).c_str() <<endl;
    136         CloseHandle(hMonitorDirHandle);
    137         return 0;
    138     }
    139 
    140     hMonitorEventHandle = CreateEvent(NULL,TRUE,FALSE,NULL);
    141 
    142     DWORD threadId = 0;
    143     hThreadHandle = CreateThread(NULL,0,MonitorThread,NULL,0,&threadId);
    144 
    145 
    146     cout<<"开始监控本程序所在的文件夹..."<<endl;
    147     int i=0;
    148     cin>>i;
    149 
    150     CloseHandle(hThreadHandle);
    151     CloseHandle(hMonitorDirHandle);
    152     CloseHandle(hMonitorEventHandle);
    153     return 0;
    154 }
    155 //---------------------------------------------------------------------------
  • 相关阅读:
    输出最大值 (10 分)
    对象数组初始化 (10 分)
    2018Final静态成员(黑名单)
    寻找回文子串(python)
    cpp-week_one-错题整理
    Python 读入多个整数
    C语言学习—strcpy()和strcat()
    javascript数学对象、自定义对象10.0
    javascript基础DOM对象6.2
    javascript基础DOM对象6.1
  • 原文地址:https://www.cnblogs.com/songr/p/4168320.html
Copyright © 2020-2023  润新知