相关文章推荐
好帅的西装  ·  Vue3.0 ...·  6 月前    · 
不爱学习的电梯  ·  std vector string to ...·  7 月前    · 
乐观的冰棍  ·  Compiler Error C2280 ...·  11 月前    · 

C/C++实现监控目录文件变化

作者:微软技术分享

ReadDirectoryChangesW是Windows操作系统提供的一个函数,用于监视目录的变化,本文主要为大家介绍了如何使用ReadDirectoryChangesW实现监控目录文件变化,需要的可以参考下

监视对指定目录的更改,并将有关更改的信息打印到控制台,该功能的实现不仅可以在内核层,在应用层同样可以。程序中使用 ReadDirectoryChangesW 函数来监视目录中的更改,并使用 FILE_NOTIFY_INFORMATION 结构来获取有关更改的信息。

ReadDirectoryChangesW 是 Windows 操作系统提供的一个函数,用于监视目录的变化。它属于 Windows API 的一部分,主要用于监视文件系统中目录的修改、新增、删除等变化,并通过回调函数向应用程序提供通知。

以下是该函数的声明:

BOOL ReadDirectoryChangesW(
  HANDLE                hDirectory,
  LPVOID                lpBuffer,
  DWORD                 nBufferLength,
  BOOL                  bWatchSubtree,
  DWORD                 dwNotifyFilter,
  LPDWORD               lpBytesReturned,
  LPOVERLAPPED          lpOverlapped,
  LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
  • hDirectory:要监视的目录的句柄。
  • lpBuffer:接收变更通知的缓冲区。
  • nBufferLength:缓冲区的大小。
  • bWatchSubtree:如果为 TRUE,则监视目录树中的所有目录。如果为 FALSE,则仅监视指定的目录。
  • dwNotifyFilter:指定要监视的变更类型,可以是文件夹或文件的新增、删除、修改等。
  • lpBytesReturned:返回实际读取到的字节数。
  • lpOverlapped:用于异步操作的 OVERLAPPED 结构。
  • lpCompletionRoutine:指定一个回调函数,在异步操作完成时调用。

在使用这个函数时,通常会在回调函数中处理具体的文件变更信息。ReadDirectoryChangesW通常用于异步操作,因此在调用时需要提供一个OVERLAPPED结构或使用同步的方式等待变更。

如下代码中使用CreateThread函数创建一个线程,并将MonitorFileThreadProc运行起来,此函数使用带有FILE_LIST_directory标志的CreateFile打开指定的目录,该标志允许该函数监视目录。并使用ReadDirectoryChangesW函数读取目录中的更改,传递一个缓冲区来存储更改,并指定要监视的更改类型。

使用WideCharToMultiByte函数将宽字符文件名转换为多字节文件名,并将文件名与目录路径连接以获得文件的完整路径。然后,该功能将有关更改的信息打印到控制台。

#include <stdio.h>
#include <Windows.h>
#include <tlhelp32.h>
DWORD WINAPI MonitorFileThreadProc(LPVOID lParam)
  char *pszDirectory = (char *)lParam;
  BOOL bRet = FALSE;
  BYTE Buffer[1024] = { 0 };
  FILE_NOTIFY_INFORMATION *pBuffer = (FILE_NOTIFY_INFORMATION *)Buffer;
  DWORD dwByteReturn = 0;
  HANDLE hFile = CreateFile(pszDirectory, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
  if (INVALID_HANDLE_VALUE == hFile)
    return 1;
  while (TRUE)
    ZeroMemory(Buffer, sizeof(Buffer));
    // 设置监控目录回调函数
    bRet = ReadDirectoryChangesW(hFile,&Buffer,sizeof(Buffer),TRUE,
      FILE_NOTIFY_CHANGE_FILE_NAME |      // 修改文件名
      FILE_NOTIFY_CHANGE_ATTRIBUTES |     // 修改文件属性
      FILE_NOTIFY_CHANGE_LAST_WRITE,      // 最后一次写入
      &dwByteReturn, NULL, NULL);
    if (TRUE == bRet)
      char szFileName[MAX_PATH] = { 0 };
      // 将宽字符转换成窄字符,宽字节字符串转多字节字符串
      WideCharToMultiByte(CP_ACP,0,pBuffer->FileName,(pBuffer->FileNameLength / 2),
        szFileName,MAX_PATH,NULL,NULL);
      // 将路径与文件连接成完整文件路径
      char FullFilePath[1024] = { 0 };
      strncpy(FullFilePath, pszDirectory, strlen(pszDirectory));
      strcat(FullFilePath, szFileName);
      switch (pBuffer->Action)
        case FILE_ACTION_ADDED:
          printf("添加: %s \n", FullFilePath); break;
        case FILE_ACTION_REMOVED:
          printf("删除: %s \n", FullFilePath); break;
        case FILE_ACTION_MODIFIED:
          printf("修改: %s \n", FullFilePath); break;
        case FILE_ACTION_RENAMED_OLD_NAME:
          printf("重命名: %s", szFileName);
          if (0 != pBuffer->NextEntryOffset)
            FILE_NOTIFY_INFORMATION *tmpBuffer = (FILE_NOTIFY_INFORMATION *)
              ((DWORD)pBuffer + pBuffer->NextEntryOffset);
            switch (tmpBuffer->Action)
                case FILE_ACTION_RENAMED_NEW_NAME:
                  ZeroMemory(szFileName, MAX_PATH);
                  WideCharToMultiByte(CP_ACP,0,tmpBuffer->FileName,
                    (tmpBuffer->FileNameLength / 2),
                    szFileName,MAX_PATH,NULL,NULL);
                  printf(" -> %s \n", szFileName);
                  break;
          break;
        case FILE_ACTION_RENAMED_NEW_NAME:
          printf("重命名(new): %s \n", FullFilePath); break;
  CloseHandle(hFile);
  return 0;
int main(int argc, char * argv[])
  char *pszDirectory = "C:\\";
  HANDLE hThread = CreateThread(NULL, 0, MonitorFileThreadProc, pszDirectory, 0, NULL);
  WaitForSingleObject(hThread, INFINITE);
  CloseHandle(hThread);
  return 0;

运行后监控C盘所有文件的变化,并输出如下信息;

到此这篇关于C/C++实现监控目录文件变化的文章就介绍到这了,更多相关C++监控目录文件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
  • Qt使用QListWidget实现自定义Item
    Qt使用QListWidget实现自定义Item
    2023-10-10
  • C++排序算法之插入排序解析
    C++排序算法之插入排序解析
    2023-10-10
  • Qt中QMapIterator检测是否为空的实现
    Qt中QMapIterator检测是否为空的实现
    2023-10-10
  • C/C++实现磁盘相关操作的示例代码
    C/C++实现磁盘相关操作的示例代码
    2023-10-10
  • C/C++实现重置文件时间戳
    C/C++实现重置文件时间戳
    2023-10-10
  • windows下用c++获取本机ip地址的三种方法
    windows下用c++获取本机ip地址的三种方法
    2023-10-10
  • C/C++获取主机网卡MAC地址的三方法
    C/C++获取主机网卡MAC地址的三方法
    2023-10-10
  • 美国设下计谋,用娘炮文化重塑日本,已影响至中国
    美国设下计谋,用娘炮文化重塑日本,已影响至中国
    2021-11-19
  • 时空伴随者是什么意思?时空伴随者介绍
    时空伴随者是什么意思?时空伴随者介绍
    2021-11-09
  • 工信部称网盘企业免费用户最低速率应满足基本下载需求,天翼云盘回应:坚决支持,始终
    工信部称网盘企业免费用户最低速率应满足基本下载需求,天翼云盘回应:坚决支持,始终
    2021-11-05
  • 2022年放假安排出炉:五一连休5天 2022年所有节日一览表
    2022年放假安排出炉:五一连休5天 2022年所有节日一览表
    2021-10-26
  • 电脑版 - 返回首页

    2006-2024 脚本之家 JB51.Net , All Rights Reserved.
    苏ICP备14036222号