FileSystemWatcher监视移动的文件

本文关键字:文件 移动 监视 FileSystemWatcher | 更新日期: 2023-09-27 18:04:29

可能重复:
使用FileSystemWatcher 检测移动的文件

我正试图用FileSystemWatcher监控移动的文件,并在这里得到了一些帮助:

使用FileSystemWatcher与多个文件

然而,我发现我必须能够同时使用Deleted和Created事件,才能获得文件移动的路径以及文件移动的位置的路径。但是,当我为Delete事件添加类似的代码时,我只能触发一个或另一个事件。它似乎是我连接事件的顺序,决定了哪个事件将运行。因此,如果我把Created事件放在连接代码的最后,它就会运行,反之亦然,如果我将Delete连接放在最后,它会运行,但不会运行Created。

这是代码:

public class FileListEventArgs : EventArgs
{
    public List<string> FileList { get; set; }
}
public class Monitor
{
    private List<string> filePaths;
    private List<string> deletedFilePaths;
    private ReaderWriterLockSlim rwlock;
    private Timer processTimer;
    private Timer deletionTimer;
    public event EventHandler FileListCreated;
    public event EventHandler FileListDeleted;

    public void OnFileListCreated(FileListEventArgs e)
    {
        if (FileListCreated != null)
            FileListCreated(this, e);
    }
    public void OnFileListDeleted(FileListEventArgs e)
    {
        if (FileListDeleted != null)
            FileListDeleted(this, e);
    }
    public Monitor(string path)
    {
        filePaths = new List<string>();
        deletedFilePaths = new List<string>();
        rwlock = new ReaderWriterLockSlim();
        FileSystemWatcher watcher = new FileSystemWatcher();
        watcher.Filter = "*.*";
        watcher.Deleted += new FileSystemEventHandler(watcher_Deleted);
        watcher.Created += watcher_FileCreated;

        watcher.Path = path;
        watcher.IncludeSubdirectories = true;
        watcher.EnableRaisingEvents = true;
    }

    private void ProcessQueue()
    {
        try
        {
            Console.WriteLine("Processing queue, " + filePaths.Count + " files created:");
            rwlock.EnterReadLock();
        }
        finally
        {
            if (processTimer != null)
            {
                processTimer.Stop();
                processTimer.Dispose();
                processTimer = null;
                OnFileListCreated(new FileListEventArgs { FileList = filePaths });
                filePaths.Clear();
            }
            rwlock.ExitReadLock();
        }
    }
    private void ProcessDeletionQueue()
    {
        try
        {
            Console.WriteLine("Processing queue, " + deletedFilePaths.Count + " files created:");
            rwlock.EnterReadLock();
        }
        finally
        {
            if (processTimer != null)
            {
                processTimer.Stop();
                processTimer.Dispose();
                processTimer = null;
                OnFileListDeleted(new FileListEventArgs { FileList = deletedFilePaths });
                deletedFilePaths.Clear();
            }
            rwlock.ExitReadLock();
        }
    }
    void watcher_FileCreated(object sender, FileSystemEventArgs e)
    {
        try
        {
            rwlock.EnterWriteLock();
            filePaths.Add(e.FullPath);
            if (processTimer == null)
            {
                // First file, start timer.
                processTimer = new Timer(2000);
                processTimer.Elapsed += (o, ee) => ProcessQueue();
                processTimer.Start();
            }
            else
            {
                // Subsequent file, reset timer. 
                processTimer.Stop();
                processTimer.Start();
            }
        }
        finally
        {
            rwlock.ExitWriteLock();
        }
    }
    void watcher_Deleted(object sender, FileSystemEventArgs e)
    {
        try
        {
            rwlock.EnterWriteLock();
            deletedFilePaths.Add(e.FullPath);
            if (deletionTimer == null)
            {
                // First file, start timer.
                deletionTimer = new Timer(2000);
                deletionTimer.Elapsed += (o, ee) => ProcessDeletionQueue();
                deletionTimer.Start();
            }
            else
            {
                // Subsequent file, reset timer. 
                deletionTimer.Stop();
                deletionTimer.Start();
            }
        }
        finally
        {
            rwlock.ExitWriteLock();
        }
    }

那么,我该如何获取文件所在的原始路径,以及文件移动位置的新路径呢?(请参阅第一个问题,了解为什么会有计时器代码,以便在多文件移动中移动完所有文件后再处理事件(。

FileSystemWatcher监视移动的文件

您声明了两个定时器,但只使用其中一个(在进程删除队列方法中使用相同的一个(。所以一开始看起来像是一个简单的复制/粘贴错误。

我发现FileSystemWatcher事件没有排队(注意:这大约是8年前的事了(。

如果您正在处理一个文件,并且在处理过程中创建了3个新文件,则不会获得这3个事件。

处理完文件后,您可能需要手动检查目录中是否有其他更改。