vc++ 监控指定路径下文件变化实现代码

参考MSDN文档

https://docs.microsoft.com/zh-cn/windows/desktop/api/winbase/nf-winbase-readdirectorychangesw

https://docs.microsoft.com/zh-cn/windows/desktop/api/winnt/ns-winnt-_file_notify_information

具体看代码

# include < iostream >
 # include < windows.h >
 # include < process.h >
 # include < tchar.h >
 # include < string >
using namespace std;
typedef void( * CHANGESCALLBACK)(const std::wstring strFileName);
/*
@ 监控指定目录下文件变化
@ strDirPath 需要监控的目录
@ dwChangesType 需要监控文件变化方式
@ onCallBack 变化后的回调处理函数
 */
void CheckFilesChanges(const std::wstring strDirPath, DWORD dwChangesType, CHANGESCALLBACK onCallBack);
void PrintMsg(const std::wstring strFileName) {
  wprintf_s(L "new add File:\t %s\r\n", strFileName.c_str());
}
void CheckFilesChanges(const std::wstring strDirPath, DWORD dwChangesType, CHANGESCALLBACK onCallBack) {
  if (strDirPath.empty() || !onCallBack)
    return;
  HANDLE hDir = INVALID_HANDLE_VALUE;
  BYTE lpBuffer[1024];
  ZeroMemory(lpBuffer, 1024);
  DWORD cbBytes = NULL;
  BOOL isOk = FALSE;
  FILE_NOTIFY_INFORMATION * pnotify = (FILE_NOTIFY_INFORMATION * )lpBuffer;
  FILE_NOTIFY_INFORMATION * tmp;
  ZeroMemory( & lpBuffer, sizeof(FILE_NOTIFY_INFORMATION));
  hDir = CreateFile(strDirPath.c_str(), FILE_LIST_DIRECTORY,
      FILE_SHARE_READ |
      FILE_SHARE_WRITE |
      FILE_SHARE_DELETE, NULL,
      OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS |
      FILE_FLAG_OVERLAPPED, NULL);
  if (INVALID_HANDLE_VALUE == hDir)
    return;
  while (true) {
    isOk = ReadDirectoryChangesW(hDir, & lpBuffer,
        sizeof(lpBuffer),
        TRUE,
        FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE,
         & cbBytes,
        NULL,
        NULL);
    if (isOk) {
      tmp = pnotify;
      PWSTR fileName = nullptr;
      std::wstring strFileName;
      if (tmp->FileNameLength) {
        DWORD dwLength = tmp->FileNameLength + 1;
        fileName = new wchar_t[dwLength];
        if (fileName) {
          memset(fileName, 0, dwLength * 2);
          memcpy(fileName, tmp->FileName, dwLength * 2);
          strFileName = fileName;
        }
        if (fileName)
          delete []fileName;
      }
      if (tmp->Action == dwChangesType) {
        onCallBack(strFileName);
      }
      ZeroMemory(tmp, 1024);
      /*switch (tmp->Action){
      case FILE_ACTION_ADDED: //当前目录新增文件{
      onCallBack(strFileName);
      }break;

      case FILE_ACTION_REMOVED:  //该文件已从目录中删除{
      onCallBack(strFileName);
      }
      break;
      case FILE_ACTION_MODIFIED: //该文件已被修改。也可以是时间戳或属性的更改{
      onCallBack(strFileName);
      }
      break;
      case FILE_ACTION_RENAMED_OLD_NAME: //该文件已重命名,这是旧名称。{
      onCallBack(strFileName);
      }
      break;
      case FILE_ACTION_RENAMED_NEW_NAME: //该文件已重命名,这是新名称。{
      onCallBack(strFileName);
      }
      break;
      default:
      break;
      }*/
    }
  }
  CloseHandle(hDir);
}
unsigned int CALLBACK ThreadProc(void * arg) {
  CheckFilesChanges(_T("E:\\GoCode"), FILE_ACTION_ADDED, PrintMsg);
  return 0;
}
int main(int argc, char * argv[]) {
  HANDLE hThread = NULL;
  hThread = (HANDLE)::_beginthreadex(nullptr, NULL, ThreadProc, NULL, NULL, NULL);
  system("pause");
  return 0;
}

好了这篇文章就介绍到这了,需要的朋友可以参考一下。

(0)

相关推荐

  • C++与namespace有关的两个编译错误的讲解

    某次,在大型的工程代码中,我这样调用: #include <iostream> using namespace std; namespace A { void fun() { printf("aaa\n"); } } namespace B { void fun() { printf("bbb\n"); } } int main() { fun(); return 0; } 编译出错:error: 'fun' was not declared in th

  • C++类中变量也可以是引用的代码实例

    C++类中变量也可以是引用哈------要用初始化列表来初始化(因为C++引用一旦绑定,就无法更换,有点类似const) #include <iostream> using namespace std; class A { public: int &x; int &y; A(int &tmpX, int &tmpY):x(tmpX), y(tmpY){} }; int main() { int tmpX = 1; int tmpY = 2; A a(tmpX,

  • c++文件监控之FileSystemWatcher

    具体代码如下: #using <System.dll> #include <iostream> using namespace std; using namespace System; using namespace System::IO; using namespace System::Security::Permissions; public ref class Watcher { private: // Define the event handlers. static vo

  • C++中rapidjson将map转为json的方法

    rapidjson将map转为json------人生苦短,我用rapidjson 直接撸代码: #include <iostream> #include <map> // 请自己下载开源的rapidjson #include "rapidjson/prettywriter.h" #include "rapidjson/rapidjson.h" #include "rapidjson/document.h" #includ

  • C++中rapidjson组装继续简化的方法

    rapidjson组装继续简化------人生苦短,我用rapidjson 看最简单的: #include <iostream> #include <stdio.h> #include<unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include<sstream> // 请自己下载开源的rapidjson #includ

  • C++中rapidjson将嵌套map转为嵌套json的讲解

    rapidjson将嵌套map转为嵌套json------人生苦短,我用rapidjson 看代码: #include <iostream> #include <map> // 请自己下载开源的rapidjson #include "rapidjson/prettywriter.h" #include "rapidjson/rapidjson.h" #include "rapidjson/document.h" #incl

  • 用C/C++代码检测ip能否ping通(配合awk和system可以做到批量检测)

    遇到一个小需求, 快速搞定. 来看看用C/C++代码检测ip能否ping通: #include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> using namespace std; string getCmdResult(const string &strCmd) // 这个是获取命令执行的结果, 类似于

  • 详解C++中虚析构函数的作用及其原理分析

    C++中的虚析构函数到底什么时候有用的,什么作用呢. 一.虚析构函数的作用 总的来说虚析构函数是为了避免内存泄露,而且是当子类中会有指针成员变量时才会使用得到的.也就说虚析构函数使得在删除指向子类对象的基类指针时可以调用子类的析构函数达到释放子类中堆内存的目的,而防止内存泄露的. 我们知道,用C++开发的时候,用来做基类的类的析构函数一般都是虚函数.可是,为什么要这样做呢?下面用一个小例子来说明: #include<iostream> using namespace std; class Cl

  • C++中rapidjson组装map和数组array的代码示例

    rapidjson组装map和数组array的代码示例 直接上码: #include <iostream> #include <map> // 请自己下载开源的rapidjson #include "rapidjson/prettywriter.h" #include "rapidjson/rapidjson.h" #include "rapidjson/document.h" #include "rapidjs

  • string居然也可以用<<和>>

    最近在项目工程中碰到一段代码, 颇为费解, string居然也可以用 <<和>>, 于是我单独写了个小程序测了一下: #include <iostream> #include <string> using namespace std; int main() { int a = 1; string s; s << a; return 0; } 编译错误:error: no match for 'operator<<' in 's <

随机推荐