• 文件监控


    来源:http://blog.sina.com.cn/s/blog_a6fb6cc901017urz.html

    文件监控之FileSystemWatcher(C++详解)

    些天在研究一些文件监控方面的知识,把自己积累的一些小知识拿出来和大家分享一下,为了能让更多的人能够更容易看明白,我特意加了一些注释,不算很详细,但是理解起来应该更轻松一点,希望各位大虾多多指正。。。技术在于交流嘛!文件监控之FileSystemWatcher(C++详解)如果希望能多了解一些文件监控方面的知识,请参考我的另一篇文章——文件监控之ReadDirectoryChangesW(C++详解)。

     1 #using
     2 #include
     3 #include
     4 #include
     5 
     6 using namespace System;
     7 using namespace System::IO;
     8 
     9 ref class FSEventHandler
    10 {
    11      private:
    12          static int count = 0;
    13 
    14          void OnChanged (Object^ source, FileSystemEventArgs^ e)
    15          {
    16               //当文件改变、创建、或者删除时执行的动作(count用于批量监控,可以测试由于粘贴大批量文件而是否引发监测漏洞问题)
    17           Console::WriteLine("{0}   File:{1}   ChangeType:{2}",
    18               ++count, e->FullPath, e->ChangeType,  e->Name);
    19          }
    20 
    21          void OnRenamed(Object^ source, RenamedEventArgs^ e)
    22          {
    23               //定义文件重命名时执行的动作
    24           Console::WriteLine("{0}   File:{1}   renamed to:{2}",
    25             ++count, e->OldFullPath, e->FullPath);
    26          }
    27 
    28      public:
    29          int static run()
    30          {
    31               //创建一个FileSystemWatcher并设置它的属性.
    32               FileSystemWatcher^ fsWatcher = gcnew FileSystemWatcher( );
    33 
    34               fsWatcher->Path = "E:\wang";
    35             
    36 
    37               //设置缓冲区大小1M,根据需求设置
    38           fsWatcher->InternalBufferSize = 1048576;
    39  
    40               //监听文件、目录、文件大小的改变
    41           fsWatcher->NotifyFilter = static_cast
    42                    (NotifyFilters::FileName |
    43                 NotifyFilters::DirectoryName |
    44                 NotifyFilters::Size);
    45 
    46               //监听子目录
    47           fsWatcher->IncludeSubdirectories = true;
    48  
    49               //添加事件处理程序
    50           FSEventHandler^ handler = gcnew FSEventHandler();
    51 
    52               fsWatcher->Changed += gcnew FileSystemEventHandler(
    53                    handler, &FSEventHandler::OnChanged);
    54 
    55               fsWatcher->Created += gcnew FileSystemEventHandler(
    56                    handler, &FSEventHandler::OnChanged);
    57 
    58                fsWatcher->Deleted += gcnew FileSystemEventHandler(
    59                        handler, &FSEventHandler::OnChanged);
    60 
    61               fsWatcher->Renamed += gcnew RenamedEventHandler(
    62                        handler, &FSEventHandler::OnRenamed);
    63 
    64               //开始监听
    65           fsWatcher->EnableRaisingEvents = true;
    66 
    67               Console::WriteLine("Press Enter to quit the sample.");
    68 
    69               Console::ReadLine();
    70               return 0;
    71          }
    72 };
    73 
    74  
    75 int main()
    76 
    77 { 
    78      FSEventHandler::run();  
    79 }

    注意事项(步骤):

    1、创建FileSystemWatcher,并设置它的属性(例如:设置监控的目录就需设置Path属性,设置缓冲区大小就需设置InternalBufferSize属性)。

    2、根据需求适当设置缓冲区大小,否则有可能会因大批量文件造成监控遗漏问题(例:同时复制或者删除1000个文件,可能只检测到500、600个)。InternalBufferSize属性用于获取或设置内部缓冲区的大小,默认值为4096(4KB)。内部缓冲区用来存储监视到的更改信息。如果短时间内更改过多,则缓冲区会发生溢出,导致某些监视到的更改数据丢失。但是增加缓冲区大小,会使系统的运行开销增大,因此,适当设置缓冲区大小,若要避免缓冲区溢出,则使用NotifyFilter和IncludeSubdirectories属性筛选掉不想要的更改通知,如果内部缓冲区溢出,组件将引发Error事件。

    3、指定在文件、文件夹中监听的更改(例:NotifyFilters::FileName | NotifyFilters::DirectoryName | NotifyFilters::Size监听文件、目录、文件大小的改变)

    4、监听子目录,设置fsWatcher->IncludeSubdirectories = true;

    5、添加事件处理程序,主要包括:Changed、Create、Delete、Ranamed。

     

    以下为我将InternalBufferSize的大小设置为1M的时候监听同时删除12000个文本文档的截图,

     

     

     

     

     

    来源:http://blog.sina.com.cn/s/blog_a6fb6cc901017us1.html

    文件监控之ReadDirectoryChangesW(C++详解)

    上篇文章跟大家分享了关于FileSystemWatcher来实现对文件夹的监控,这篇文章主要介绍文件监控的另一种实现方式,利用ReadDirectoryChangesW来实现文件的监控,希望对大家有帮助!文件监控之ReadDirectoryChangesW(C++详解)

     1 #include
     2 #include
     3 #include
     4 #include
     5 using namespace std;
     6 #define MAX_PATH 1024
     7  
     8 
     9 void fileWatcher();
    10 
    11 int main()
    12 {
    13      fileWatcher();
    14      return 0;
    15 } 
    16 
    17 void fileWatcher()
    18 {
    19      DWORD cbBytes;
    20      char file_name[MAX_PATH]; //设置文件名
    21     char file_name2[MAX_PATH]; //设置文件重命名后的名字
    22     char notify[1024];
    23      int count = 0; //文件数量。可能同时拷贝、删除多个文件,可以进行更友好的提示。
    24 
    25     TCHAR *dir = _T("E:\liang");
    26 
    27      HANDLE dirHandle = CreateFile(dir,GENERIC_READ | GENERIC_WRITE | FILE_LIST_DIRECTORY,
    28          FILE_SHARE_READ | FILE_SHARE_WRITE,
    29          NULL,
    30          OPEN_EXISTING,
    31          FILE_FLAG_BACKUP_SEMANTICS,
    32          NULL);
    33 
    34      if(dirHandle == INVALID_HANDLE_VALUE) //若网络重定向或目标文件系统不支持该操作,函数失败,同时调用GetLastError()返回ERROR_INVALID_FUNCTION
    35      {
    36          cout<<"error"+GetLastError()<<endl;
    37      }
    38 
    39      memset(notify,0,strlen(notify));
    40 
    41      FILE_NOTIFY_INFORMATION *pnotify = (FILE_NOTIFY_INFORMATION*)notify; 
    42      cout<<"start...."<<endl;   
    43 
    44      while(true)
    45      {   
    46          if(ReadDirectoryChangesW(dirHandle,&notify,1024,true,
    47               FILE_NOTIFY_CHANGE_FILE_NAME |
    48               FILE_NOTIFY_CHANGE_DIR_NAME
    49               //| FILE_NOTIFY_CHANGE_CREATION
    50               //| FILE_NOTIFY_CHANGE_LAST_WRITE
    51               | FILE_NOTIFY_CHANGE_SIZE,
    52               &cbBytes,NULL,NULL))
    53          {
    54               //转换文件名为多字节字符串
    55           if(pnotify->FileName)
    56               {
    57                   memset(file_name,0,strlen(file_name));
    58 
    59                    WideCharToMultiByte(CP_ACP,0,pnotify->FileName,pnotify->FileNameLength/2,file_name,99,NULL,NULL);
    60               }
    61 
    62                //获取重命名的文件名
    63          if(pnotify->NextEntryOffset !=0 && (pnotify->FileNameLength > 0 && pnotify->FileNameLength < MAX_PATH)) 
    64 
    65             { 
    66                    PFILE_NOTIFY_INFORMATION p = (PFILE_NOTIFY_INFORMATION)((char*)pnotify+pnotify->NextEntryOffset); 
    67 
    68                    memset(file_name2,0,sizeof(file_name2) ); 
    69 
    70                    WideCharToMultiByte(CP_ACP,0,p->FileName,p->FileNameLength/2,file_name2,99,NULL,NULL ); 
    71               } 
    72 
    73               //设置类型过滤器,监听文件创建、更改、删除、重命名等
    74           switch(pnotify->Action)
    75               {
    76                    case FILE_ACTION_ADDED:
    77                        count++;
    78                        cout<<count<<setw(5)<<"file add:"<<setw(5)<<file_name<<endl;
    79                        break;
    80                    case FILE_ACTION_MODIFIED:
    81                        cout<<"file modified:"<<setw(5)<<file_name<<endl;
    82                        break;
    83                    case FILE_ACTION_REMOVED:
    84                        count++;
    85                        cout<<count<<setw(5)<<"file removed:"<<setw(5)<<file_name<<endl;
    86                        break;
    87                    case FILE_ACTION_RENAMED_OLD_NAME:
    88                        cout<<"file renamed:"<<setw(5)<<file_name<<"->"<<file_name2<<endl;
    89                        break;
    90                   default:
    91                        cout<<"unknow command!"<<endl;
    92               }
    93          }   
    94      }
    95 
    96      CloseHandle(dirHandle);
    97 }

    注意事项(步骤):

    1、通过CreateFile获取要监控的目录句柄。

    2、通过ReadDirectoryChangesW来监测到文件系统的变化,还能够返回详细的文件变动的信息,并且能够选择是使用同步方式检测还是异步方式监测。

    3、通过Action设置类型过滤器,根据过滤器的设置,ReadDirectoryChangesW函数可以监控文件名改变、文件属性改变、文件大小改变、文件内容被改写、文件被删除等多种类型的变化。

  • 相关阅读:
    c# 泛型委托
    c# 用户自定义转换
    c# 溢出上下文检测
    c# 接口相同方法申明使用
    c# 事件的订阅发布Demo
    c# 匿名方法几种表现形式
    c# 数组协变
    c# 交错数组
    C# 位运算详解
    ABAP 7.4 新语法-内嵌生命和内表操作(转)
  • 原文地址:https://www.cnblogs.com/spriteflk/p/4863305.html
Copyright © 2020-2023  润新知