【发布时间】:2011-08-05 17:30:55
【问题描述】:
我正在尝试使用 FileSystemWatcher 监控移动的文件,并在此过程中获得了一些帮助:
Using FileSystemWatcher with multiple files
但是,我发现我必须能够同时使用 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();
}
}
那么,我该如何获取文件所在的原始路径以及它们被移动的新路径? (请参阅第一个问题,了解为什么存在计时器代码以推迟对事件的处理,直到所有文件都已在多文件移动中移动)。
【问题讨论】:
-
我不这么认为。就像那篇文章一样,我使用文件名来比较文件没有问题。问题是我无法同时触发删除和创建事件。或者至少我所看到的是创建事件被触发并且删除还没有这样做。在我的主类中,我需要获取创建的文件列表并将其与已删除的文件列表进行比较,但已删除的文件列表为空,而创建的文件列表已填充。
标签: c# filesystemwatcher