加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – FileSystemWatcher触发filestream打开

发布时间:2020-12-15 06:15:04 所属栏目:百科 来源:网络整理
导读:我有一个filesystemwatcher将在文件被修改时触发一个事件.一旦锁已被删除,我想从该文件读取.目前我只是在触发事件时尝试打开文件,当复制一个大文件时,文件锁在事件发送后保持一段时间,阻止文件被打开以进行读取访问. 有什么建议么? 解决方法 这实际上是一个
我有一个filesystemwatcher将在文件被修改时触发一个事件.一旦锁已被删除,我想从该文件读取.目前我只是在触发事件时尝试打开文件,当复制一个大文件时,文件锁在事件发送后保持一段时间,阻止文件被打开以进行读取访问.

有什么建议么?

解决方法

这实际上是一个doozie,除非问题的空间已经发生了重大变化,因为我最后一次处理它.

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

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

public class FileMonitor : IDisposable
{
    private const int PollInterval = 5000;

    private FileSystemWatcher watcher;
    private HashSet<string> filesToProcess = new HashSet<string>();
    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);
        }
    }
}

(注意 – 我记得这里的记忆,所以它可能不是完美的 – 让我知道,如果它是buggy.)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读