相关文章推荐

FileSystemWatcher

// <https://msdn.microsoft.com/zh-cn/library/chzww271.aspx>
// monitor_fs.cpp
// compile with: /clr
#using <system.dll>
using namespace System;
using namespace System::IO;
ref class FSEventHandler
public:
    void OnChanged (Object ^source, FileSystemEventArgs ^e)
        Console::WriteLine("File: {0} {1}",
                           e->FullPath, e->ChangeType);
    void OnRenamed(Object ^source, RenamedEventArgs ^e)
        Console::WriteLine("File: {0} renamed to {1}",
                           e->OldFullPath, e->FullPath);
int main()
    array<String ^> ^args = Environment::GetCommandLineArgs();
    if(args->Length < 2)
        Console::WriteLine("Usage: Watcher.exe <directory>");
        return -1;
    FileSystemWatcher ^fsWatcher = gcnew FileSystemWatcher( );
    fsWatcher->Path = args[1];
    fsWatcher->NotifyFilter = static_cast<NotifyFilters>
                              (NotifyFilters::FileName |
                               NotifyFilters::Attributes |
                               NotifyFilters::LastAccess |
                               NotifyFilters::LastWrite |
                               NotifyFilters::Security |
                               NotifyFilters::Size );
    FSEventHandler ^handler = gcnew FSEventHandler();
    fsWatcher->Changed += gcnew FileSystemEventHandler(
                              handler, &FSEventHandler::OnChanged);
    fsWatcher->Created += gcnew FileSystemEventHandler(
                              handler, &FSEventHandler::OnChanged);
    fsWatcher->Deleted += gcnew FileSystemEventHandler(
                              handler, &FSEventHandler::OnChanged);
    fsWatcher->Renamed += gcnew RenamedEventHandler(
                              handler, &FSEventHandler::OnRenamed);
    fsWatcher->EnableRaisingEvents = true;
    Console::WriteLine("Press Enter to quit the sample.");
    Console::ReadLine( );

目录监视器(Directory Monitor)

使用Boost.Asio扩展
http://www.highscore.de/boost/dir_monitor.zip

SHChangeNotifyRegister

Win SDK Samples 下 ChangeNotifyWatcher 项目,使用 SHChangeNotifyRegister

使用SHChangeNotifyRegister、FindFirstChangeNotification、ReadDirectoryChangesW

windows下文件的监控–ReadDirectoryChangesW函数的使用

监控文件和目录的四种方式

以下内容引用 理解 ReadDirectoryChangesW

在 Windows Vista 中,SHChangeNotifyRegister 已经可以报告所有文件的所有变更。但问题是,还存在上亿不打算立即升级的 Windows XP 用户。

由于 SHChangeNotifyRegister 基于窗口消息,所以还会带来性能上的问题。如果发生了太多文件变更,应用程序会不断接收到变更消息,你必须自己确认实际发生的事情。对于一部分应用程序来说,这实在是相当的囧。

Windows 2000 引入了两个新接口, FindFirstChangeNotification .aspx) 和 ReadDirectoryChangesW .aspx)。 FindFirstChangeNotification 很容易使用,但没有给出变更文件的信息。即便如此,这个函数对某些应用程序还是很有用的,比如传真服务和 SMTP 服务可以通过拖拽一个文件到一个目录来接受任务队列。ReadDirectoryChangesW 会给出变更的内容和方式, 不过相对的,在使用上也更复杂一些。

同 SHChangeNotifyRegister 一样,这两个新函数也会有性能问题。与 Shell 通知相比,它们的运行速度有明显提升,但在不同目录间移动上千个文件仍然会导致你丢失一部分(或者很多)通知。丢失通知的原因很 复杂 。令人惊讶的是,似乎与你处理通知的速度有关。

注意,FindFirstChangeNotification 和 ReadDirectoryChangesW 是互斥的,不能同时使用。

Windows XP 引入了最终解决方案,变更日志( Change Journal .aspx))可以跟踪每一个变更的细节,即使你的软件没有运行。很帅的技术,但也相当难用。

第四个,同时也是最后一个解决方案需要安装 文件系统过滤驱动 ,Sysinternals 的 FileMon 就使用了这种技术。在 Windows 驱动开发包(WDK)中有一个例子。这个方案本质上是一个 设备驱动 ,如果没有正确的实现,有可能导致系统稳定性方面的问题。

对我来说,使用 ReadDirectoryChangesW,在性能和复杂度上会是一个很好的平衡。

使用 ReadDirectoryChangesW 的最大挑战在于,在IO模式,处理信号,等待方式,以及线程模型这几个问题的整合上,存在数百种可能性。如果你不是 Win32 I/O 方面的专家,即使最简单的场景,你也很难搞定。

A. I/O模式:

阻塞同步(Blocking synchronous)
触发式同步(Signaled synchronous)
重叠异步(Overlapped asynchronous)
完成例程(Completion Routine) (又名 Asynchronous Procedure Call or APC)

B. 当调用 WaitForXxx 函数的时候:

等待目录句柄
等待 OVERLAPPED 结构体里的 Event 对象
什么都不等 (APCs)

C. 处理通知:

WaitForSingleObject WaitForMultipleObjects WaitForMultipleObjectsEx MsgWaitForMultipleObjectsEx IO完成端口(I/O Completion Ports)

D. 线程模型:

每个工作线程调用一次 ReadDirectoryChangesW.
每个工作线程调用多次 ReadDirectoryChangesW.
在主线程上调用多次 ReadDirectoryChangesW.
多个线程进行多个调用. (I/O Completion Ports)

最后,当调用 ReadDirectoryChangesW 的时候,你可以通过 flags 选择你要监控的内容,包括文件创建,内容变更,属性变更等等。你可以多次调用,每次一个 flag,也可以在一次调用中使用多个 flag。多个 flag 总是正确的解决方案。但如果你为了调试方便,需要一个 flag 一个 flag 的调用的话,那就需要从 ReadDirectoryChangesW 返回的通知缓冲区中读取更多的数据。

QFileSystemWatcher

Qt的QFileSystemWatcher也可监控目录

缺失模块。
1、请确保node版本大于6.2
2、在博客根目录(注意不是yilia根目录)执行以下命令:
npm i hexo-generator-json-content --save

3、在根目录_config.yml里添加配置: jsonContent: meta: false pages: false posts: title: true date: true path: true text: false raw: false content: false slug: false updated: false comments: false link: false permalink: false excerpt: false categories: false tags: true
 
推荐文章