回答网友一个文件监控的问题

起因

网友说:他有个需求是监控一个目录的文件,当文件内容发送变化时,自动处理文件,把文件内的数据同步到另外一个系统中,他目前使用的是Timer 进行判断。

俺的回答

俺推荐了 FileSystemWatcher 。FileSystemWatcher 文件系统监控功能,可以实时监听指定目录下的文件创建、修改、删除和重命名事件。相比Timer轮询方式更方便高效,支持设置NotifyFilter过滤条件,并包含子目录监控。使用时只需初始化监控路径,绑定对应事件处理程序即可实现文件变更时的自动处理功能。具体事件如下:

NotifyFilter = NotifyFilters.Attributes | NotifyFilters.CreationTime | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.Security | NotifyFilters.Size;

其实这个功能 俺第一次使用是在 delphi6上,25年前吧。大部分语音其实都自动了这个功能,只是名字不一样。delphi中叫做TShellChangeNotifier 

type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
FNotifier: TShellChangeNotifier;
public
{ Public declarations }
end;
var
Form1: TForm1;
procedure TForm1.FormCreate(Sender: TObject);
begin
FNotifier := TShellChangeNotifier.Create(nil);
FNotifier.OnChange := procedure(Sender: TObject)
begin
// 处理文件系统变化事件
MessageBox(0, '文件系统已更改', '通知', MB_OK);
end;
end;

例子

我们先定义一个类 DirectoryWatcher

using System;
using System.IO;

public class DirectoryMonitor : IDisposable
{
private readonly FileSystemWatcher _watcher;
public event EventHandler<FileSystemEventArgs> FileCreated;
public event EventHandler<FileSystemEventArgs> FileChanged;
public event EventHandler<FileSystemEventArgs> FileDeleted;
public event EventHandler<RenamedEventArgs> FileRenamed;

public DirectoryMonitor(string path, string filter = "*.*")
{
    _watcher = new FileSystemWatcher(path, filter)
    {
        NotifyFilter = NotifyFilters.FileName | 
                     NotifyFilters.DirectoryName |
                     NotifyFilters.LastWrite |
                     NotifyFilters.Size,
        IncludeSubdirectories = true
    };

    _watcher.Created += (s, e) => FileCreated?.Invoke(this, e);
    _watcher.Changed += (s, e) => FileChanged?.Invoke(this, e);
    _watcher.Deleted += (s, e) => FileDeleted?.Invoke(this, e);
    _watcher.Renamed += (s, e) => FileRenamed?.Invoke(this, e);

    _watcher.EnableRaisingEvents = true;
}

public void Dispose() => _watcher?.Dispose();
}

然后我们使用这个类

Program
{
static void Main()
{
const string watchPath = @"C:\WatchFolder";
    using var monitor = new DirectoryMonitor(watchPath);

    monitor.FileCreated += (s, e) => 
        Console.WriteLine($"[创建] {DateTime.Now:HH:mm:ss} {e.FullPath}");

    monitor.FileChanged += (s, e) => 
        Console.WriteLine($"[修改] {DateTime.Now:HH:mm:ss} {e.FullPath}");

    monitor.FileDeleted += (s, e) => 
        Console.WriteLine($"[删除] {DateTime.Now:HH:mm:ss} {e.FullPath}");

    monitor.FileRenamed += (s, e) => 
        Console.WriteLine($"[重命名] {DateTime.Now:HH:mm:ss} {e.OldFullPath} -> {e.FullPath}");

    Console.WriteLine($"正在监控 {watchPath}...");
    Console.WriteLine("按任意键退出");
    Console.ReadKey();
}
}



微信扫描下方的二维码阅读本文

没有账号? 忘记密码?

社交账号快速登录