监控Windows文件夹下面的文件(C#和C++实现)

最近在做虚拟打印机时,需要实时监控打印文件的到达,并移动文件到另外的位置。一开始我使用了线程,在线程里去检测新文件的到达。实际上Windows提供了一个文件监控接口函数ReadDIrectoryChangesW。这个函数可以对所有文件操作进行监控。

ReadDirectoryChangesW

函数声明

 1 BOOL ReadDirectoryChangesW(2   [in]                HANDLE                          hDirectory,3   [out]               LPVOID                          lpBuffer,4   [in]                DWORD                           nBufferLength,5   [in]                BOOL                            bWatchSubtree,6   [in]                DWORD                           dwNotifyFilter,7   [out, optional]     LPDWORD                         lpBytesReturned,8   [in, out, optional] LPOVERLAPPED                    lpOverlapped,9   [in, optional]      LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
10 );

参数

hDirectory

指向要监听的目录句柄,必须使用FILE_LIST_DIRECTORY访问权限打开此目录。

lpBuffer

指向要读取DWORD对齐结果的格式化缓冲区的指针。该缓冲区的结构由FILE_NOTIFY_INFORMATION结构定义

nBufferLength

lpBuffer参数指向的缓冲区大小

bWatchSubtree

 指示是否以指定目录为根目录进行监控。

True:监视以指定目录为根的目录树

FALSE:仅监视指定目录

dwNotifyFilter

检查函数以确定等待操作是否满足过滤条件。此参数可以指定为以下的一个或多个

含义
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监视目录或子树中任何安全描述符更改

lpBytesReturned

对于同步调用,此参数接收传输到lpBuffer参数中的字节数

lpOverlapped

指向OVERLAPPED结构的指针,提供在异步操作期间要用的数据,否则该值为NULL

lpConpletionRoutine

指向完成例程的指针,当操作已经完成或取消,并且调用线程处于可警告的等待状态时才会调用它

返回值

成功:不为0

失败:0

监控指定目录下的文件创建

假设我这里要监控D:\PrintFiles目录下的文件更改,操作如下:

打开目录,获取文件句柄

     // 打开目录, 获取文件句柄HANDLE hDirectory = ::CreateFile(L"D:\\PrintFiles", FILE_LIST_DIRECTORY,FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS, NULL);if (INVALID_HANDLE_VALUE == hDirectory){return 0;}

调用ReadDirectoryChangesW监控文件夹

我这里只演示同步调用,异步调用可以参考MSDN文档。同步调用时,如果监控的目录未发生更改,会一直阻塞在那里。

      DWORD dwRet = 0;DWORD dwBufferSize = 2048;BYTE* pBuf = new BYTE[dwBufferSize];FILE_NOTIFY_INFORMATION* pFileNotifyInfo = (FILE_NOTIFY_INFORMATION*)pBuf;BOOL bRet = ReadDirectoryChangesW(hDirectory,pFileNotifyInfo, dwBufferSize,TRUE,FILE_NOTIFY_CHANGE_FILE_NAME|           //修改文件名FILE_NOTIFY_CHANGE_ATTRIBUTES |         // 修改文件属性FILE_NOTIFY_CHANGE_LAST_WRITE,          // 最后一次写入&dwRet,NULL, NULL);

输出结果

  if (FALSE == bRet){DWORD dwError = GetLastError();std::cout << "ReadDirectoryChangesW failed - " << dwError << std::endl;}std::wcout.imbue(std::locale("chs"));//判断操作类型switch (pFileNotifyInfo->Action){case FILE_ACTION_ADDED:std::wcout << "Create file " << pFileNotifyInfo->FileName << std::endl;break;default:break;}CloseHandle(hDirectory);delete[] pBuf;

运行效果

System.IO.FileSystemWatcher类

在C#中,可以使用 System.IO.FileSystemWatcher类来进行监听。它内部也是调用了ReadDirectoryChangesW API函数

监控文件的行为定义在System.IO.NotifyFilters

 1    [Flags]2     public enum NotifyFilters3     {4         FileName = 0x1,5         DirectoryName = 0x2,6         Attributes = 0x4,7         Size = 0x8,8         LastWrite = 0x10,9         LastAccess = 0x20,
10         CreationTime = 0x40,
11         Security = 0x100
12     }

在C#中是通过事件订阅的形式来进行通知的。

C#进行了再次封装,所以会比直接在C++中使用要方便一些。创建监听后,只需要等待事件触发就行了。

FileSystemWatcher使用方法如下:

              FileSystemWatcher systemWatcher = new FileSystemWatcher();systemWatcher.Path = this.textBox1.Text;//设置监听的行为//这里设置为文件名systemWatcher.NotifyFilter = NotifyFilters.FileName;//设置文件类型过滤systemWatcher.Filter = "*.txt";systemWatcher.Changed += (obj, args) => { ShowMsg($"文件更改{args.Name}"); };systemWatcher.Created += (obj, args) => { ShowMsg($"文件创建{args.Name}"); };systemWatcher.Deleted += (obj, args) => { ShowMsg($"文件删除{args.Name}"); };systemWatcher.Renamed += (obj, args) => { ShowMsg($"文件重命名{args.Name}"); };//开始监听systemWatcher.EnableRaisingEvents = true;    

运行效果

示例代码

参考资料:

ReadDirectoryChangesW function (winbase.h) - Win32 apps | Microsoft Learn

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/384704.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JS+H5在线文心AI聊天(第三方接口)

源码在最后面 调用的不是文心官方接口 可以正常聊天 有打字动画 效果图 源代码 <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-s…

目标检测自顶向下入门

最近在学习Yolo和OpenCV这些计算机视觉的相关领域&#xff0c;把深度学习啃了个大概&#xff0c;准备着手学习一下Yolov5&#xff0c;趁着这个机会入门一下目标检测这个领域&#xff0c;也算是自顶向下地学习一遍吧。 目标检测 什么是目标检测 物体识别&#xff08;Object de…

【Emacs有什么优点,用Emacs写程序真的比IDE更方便吗?】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

X-AnyLabeling标注软件使用方法

第一步 下载 官方X-AnyLabeling下载地址 github&#xff1a;X-AnyLabeling 第二步 配置环境 使用conda创建新的虚拟环境 conda create -n xanylabel python3.8进入环境 conda activate xanylabel进入X-AnyLabeling文件夹内&#xff0c;运行下面内容 依赖文件系统环境运行环…

多多OJ评测系统 在前端脚手架Vue-Cli中设置页面路由

目录 设置页面路由 我们把菜单上的路由改成读取路由文件 设置成export 导出路由 在刚刚的原始路由 index.ts中导入就行了 在这边引入我们的路由文件 我们之后点击菜单 我们的路由文件是这样的 但是没有跳转 写一下事件 接下来要同步路由到菜单项 自己定义监听函数 …

Hadoop3.3.5的安装与单机/伪分布式配置

文章目录 一、安装须知二、安装jdk三、安装shh四、安装配置hadoop五、运行hadoop 一、安装须知 本次安装的Hadoop版本为hadoop3.3.5。 在这之前完成了VMware虚拟软件的安装&#xff0c;并安装了Ubuntu22.04&#xff0c;在这基础上进行相关配置。 二、安装jdk 在Ubuntu中使用…

MICA:面向复杂嵌入式系统的混合关键性部署框架

背景 在嵌入式场景中&#xff0c;虽然 Linux 已经得到了广泛应用&#xff0c;但并不能覆盖所有需求&#xff0c;例如高实时、高可靠、高安全的场合。这些场合往往是实时操作系统的用武之地。有些应用场景既需要 Linux 的管理能力、丰富的生态&#xff0c;又需要实时操作系统的高…

计科录取75人!常州大学计算机考研考情分析!

常州大学&#xff08;Changzhou University&#xff09;&#xff0c;简称“常大”&#xff0c;位于江苏省常州市&#xff0c;是江苏省人民政府与中国石油天然气集团有限公司、中国石油化工集团有限公司及中国海洋石油集团有限公司共建的省属全日制本科院校&#xff0c;为全国深…

SQL 语句中的字符串有单引号导致报错的解决

1.问题 SQL 语句执行对象中&#xff0c;本内容的字符串内含有单引号导致查询或插入数据库报错&#xff0c; 例如 str 关键字 AND 附近有语法错误 2.解决 字符串中的 ’ → 替换 ”&#xff0c;则查询语句成功&#xff0c;故程式中要备注替换 单引号。

【科研绘图】记录一次论文结果复现

复现原论文中的图片是科研的基本功之一&#xff0c;它不仅验证了研究结果的可靠性&#xff0c;确保了科学工作的准确性和可重复性&#xff0c;还深刻地评估了方法的有效性&#xff0c;体现了对原始研究的尊重和对科学过程的严谨态度。这个过程不仅提高了研究的透明度&#xff0…

Mac 中安装内网穿透工具ngrok

ngrok 是什么&#xff1f; Ngrok 是一个网络工具&#xff0c;主要用于在网络中创建从公共互联网到私有或本地网络中运行的web服务的安全隧道。它充当了一个反向代理&#xff0c;允许外部用户通过公共可访问的URL访问位于防火墙或私有网络中的web应用程序或服务。Ngrok 特别适用…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第五十九章 等待队列

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

Java数据结构与算法--链表(Linked List)

博客主页&#xff1a;誓则盟约系列专栏&#xff1a;Java SE关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 深入了解链表&#xff1a; 链表是一种常见的数据结构&#xff0c;它由一系列节点…

【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !

目录 C语言指针精讲1. 什么是指针&#xff1f;1.1 指针的内存模型1.1.1 指针演示输出 1.2 指针运算1.2.1 指针算术运算输出1.2.2 指针与数组的关系输出 1.3 指针类型1.3.1 不同类型的指针示例输出1.3.2 void 指针输出 1.4 指针与内存管理动态内存分配输出 1.5 指针与内存泄漏1.…

Android进阶之NDK开发,保姆级教程

目录 前言NDK下载CMake文件创建指定ABI架构编写CMake文件编写JNI方法Java调用CC调用Java 生成JNI头文件实现对应C方法编译so文件编写demo验证运行效果总结 前言 作为Android应用开发从业者来说&#xff0c;掌握NDK开发是必备技能之一&#xff0c;本文将从NDK环境下载&#xff…

均匀圆形阵列原理及MATLAB仿真

均匀圆形阵列原理及MATLAB仿真 目录 前言 一、均匀圆阵原理 二、圆心不存在阵元方向图仿真 三、圆心存在阵元方向图仿真 四、MATLAB仿真代码 总结 前言 本文详细推导了均匀圆形阵列的方向图函数&#xff0c;对圆心不放置阵元和圆心放置阵元的均匀圆形阵列方向图都进行了仿…

PySide(PyQt)的QPropertyAnimation(属性动画)

学不完&#xff0c;根本学不完:(&#xff0c;感觉逐渐陷入了学习深渊。。。 QPropertyAnimation 是 PySide(PyQt) 中一个用于在时间轴上平滑地改变对象属性的类。它常用于制作动画效果&#xff0c;比如移动、缩放或改变透明度等。 基本概念 QPropertyAnimation 是 Qt …

03。正式拿捏ArkTS语言第一天

1, 打印日志命令 &#xff1a; console.log() 2, 三种基本数据类型&#xff1a; number 数字类型 &#xff08;数字&#xff09; string 字符串类型&#xff08;例如&#xff1a;“我是字符串”&#xff09; boolean 布尔类型 (true 或者 false) ***…

昇思25天学习打卡营第24天|RNN实现情感分类

RNN实现情感分类学习总结 概述 情感分类是自然语言处理领域的重要任务&#xff0c;主要用于识别文本中表达的情绪。本文使用MindSpore框架实现基于RNN的情感分类模型&#xff0c;示例包括&#xff1a; 输入: “This film is terrible” -> 标签: Negative输入: “This fi…

飞牛爬虫FlyBullSpider 一款简单方便强大的爬虫,限时免费 特别适合小白!用它爬下Boss的2024年7月底Java岗位,分析一下程序员就业市场行情

一、下载安装FlyBullSpider 暂时支持Window,现在只在Win11上做过测试 1 百度 点击百度网盘 下载 链接&#xff1a;https://pan.baidu.com/s/1gSLKYuezaZgd8iqrXhk8Kg 提取码&#xff1a;Fly6 2 csdn https://download.csdn.net/download/fencer911/89584687 二、体验初…