FileSystemWatcher触发文件流打开

我有一个filesystemwatcher,它会在修改文件时触发事件。 一旦锁定被删除,我想从该文件中读取。 目前,我只是在触发事件时尝试打开文件,当复制大文件时,文件锁在事件发送后保持一段时间,从而阻止文件被打开以进行读取访问。

有什么建议?

这个实际上有点像doozie,除非问题空间发生了重大变化,因为我上次不得不处理它。

最简单的方法是简单地尝试打开文件,捕获生成的IOException ,如果文件被锁定,则将其添加到队列中以便稍后检查。 您不能只是尝试处理每个进入的文件,因为有各种情况会为同一个文件生成多个事件,因此在每个接收到的事件上设置重试循环可能会变成灾难,速度很快。 您需要将它们排队,并定期检查队列。

这是一个基本的类模板,可以帮助您解决这个问题:

 public class FileMonitor : IDisposable { private const int PollInterval = 5000; private FileSystemWatcher watcher; private HashSet filesToProcess = new HashSet(); private Timer fileTimer; // System.Threading.Timer public FileMonitor(string path) { if (path == null) throw new ArgumentNullException("path"); watcher = new FileSystemWatcher(); watcher.Path = path; watcher.NotifyFilter = NotifyFilters.FileName; watcher.Created += new FileSystemEventHandler(FileCreated); watcher.EnableRaisingEvents = true; fileTimer = new Timer(new TimerCallback(ProcessFilesTimer), null, PollInterval, Timeout.Infinite); } public void Dispose() { fileTimer.Dispose(); watcher.Dispose(); } private void FileCreated(object source, FileSystemEventArgs e) { lock (filesToProcess) { filesToProcess.Add(e.FullPath); } } private void ProcessFile(FileStream fs) { // Your code here... } private void ProcessFilesTimer(object state) { string[] currentFiles; lock (filesToProcess) { currentFiles = filesToProcess.ToArray(); } foreach (string fileName in currentFiles) { TryProcessFile(fileName); } fileTimer.Change(PollInterval, Timeout.Infinite); } private void TryProcessFile(string fileName) { FileStream fs = null; try { FileInfo fi = new FileInfo(fileName); fs = fi.OpenRead(); } catch (IOException) { // Possibly log this error return; } using (fs) { ProcessFile(fs); } lock (filesToProcess) { filesToProcess.Remove(fileName); } } } 

(注意 – 我从记忆中回忆起这个,所以它可能并不完美 – 让我知道它是否有错误。)