使用 FileSystemWatcher 监控文件资源管理器特定文件新增、编辑、删除

使用  FileSystemWatcher  监控文件资源管理器特定文件新增、编辑、删除。因文件修改一次会引起多次回调和通知,为确保对文件处理时文件已经编辑完成,使用files 对象保存变更文件的记录,每个文件只保留一条数据,并且记录最后一次文件操作的时间。使用定时器每间隔固定时间检查几分钟之前变更的文件进行操作。

使用到的全局参数

        #region 配置文件中数据参数获取
        /// <summary>
        /// 文件监控路径,文件输入路径
        /// </summary>
        string FilePath = System.Configuration.ConfigurationSettings.AppSettings["FilePath"].ToString();
        /// <summary>
        /// 转换成功后的输出路径
        /// </summary>
        string OutPutPath = System.Configuration.ConfigurationSettings.AppSettings["OutPutPath"].ToString();
        /// <summary>
        /// 计时器执行间隔时间,多长时间检查一次变动结束的数据
        /// </summary>
        string TimeoutMillis = System.Configuration.ConfigurationSettings.AppSettings["TimeoutMillis"].ToString();
        /// <summary>
        /// 数据变更结束后等待的时间,单位秒,例如ChangedTime = 60,代表最后一次触发时间距离现在1分钟
        /// </summary>
        string ChangedTime = System.Configuration.ConfigurationSettings.AppSettings["ChangedTime"].ToString();
        #endregion
        #region 全局变量
        //异步更新UI信息
        System.IO.FileSystemWatcher watcherJson = null;//磁盘监控类,监控风轨迹和图谱
        System.IO.FileSystemWatcher watcherVtk = null;//磁盘监控类,监控风廓线和云切片
        string fileTypeJson = "*.json";
        string fileTypeVtk = "*.txt";
        #endregion
        /// <summary>
        /// 计时器处理回调
        /// </summary>
        System.Threading.Timer m_timer = null;
        /// <summary>
        /// 计时器处理事件的锁
        /// </summary>
        object timeLock = new object();
        /// <summary>
        /// 用于接受FileSystemWatcher返回的变更的信息
        /// </summary>
        List<ChangeInfo> files = new List<ChangeInfo>();
        /// <summary>
        /// 存储需要转换的文件,每隔固定时间(TimeoutMillis)进行循环
        /// </summary>
        List<ChangeInfo> backup = new List<ChangeInfo>();

文件监控逻辑

        /// <summary>
        /// 启动文件监控任务
        /// </summary>
        /// <param name="filetype"></param>
        private void FileWatcher(string filetype)
        {
            if (watcherJson == null && filetype == fileTypeJson)
            {
                watcherJson = new System.IO.FileSystemWatcher();
                watcherJson.Path = FilePath;
                watcherJson.Filter = fileTypeJson;
                watcherJson.Changed += new System.IO.FileSystemEventHandler(OnProcessChanged);
                watcherJson.Created += new System.IO.FileSystemEventHandler(OnProcessChanged);
                watcherJson.Deleted += new System.IO.FileSystemEventHandler(OnProcessChanged);
                watcherJson.Renamed += new System.IO.RenamedEventHandler(OnProcessChanged);
                watcherJson.IncludeSubdirectories = true;
                watcherJson.InternalBufferSize = 65536;
                watcherJson.EnableRaisingEvents = true;
                watcherJson.NotifyFilter = System.IO.NotifyFilters.FileName |  //文件名
                    System.IO.NotifyFilters.DirectoryName |  // 目录名
                    System.IO.NotifyFilters.Size            // 文件或文件夹的大小
                    | System.IO.NotifyFilters.Attributes |   // 文件或文件夹的特性
                    System.IO.NotifyFilters.LastWrite |      // 上一次向文件或文件夹写入内容的日期
                    System.IO.NotifyFilters.LastAccess |     // 文件或文件夹上一次打开的日期
                    System.IO.NotifyFilters.CreationTime |   // 文件或文件夹的创建时间
                    System.IO.NotifyFilters.Security;        // 文件或文件夹的安全设置
            }
            if (watcherVtk == null && filetype == fileTypeVtk)//*.vtk
            {
                watcherVtk = new System.IO.FileSystemWatcher();
                watcherVtk.Path = FilePath;
                watcherVtk.Filter = fileTypeVtk;
                watcherVtk.Changed += new System.IO.FileSystemEventHandler(OnProcessChanged);
                watcherVtk.Created += new System.IO.FileSystemEventHandler(OnProcessChanged);
                watcherVtk.Deleted += new System.IO.FileSystemEventHandler(OnProcessChanged);
                watcherVtk.Renamed += new System.IO.RenamedEventHandler(OnProcessChanged);
                watcherVtk.IncludeSubdirectories = true;
                watcherVtk.InternalBufferSize = 65536;
                watcherVtk.EnableRaisingEvents = true;
                watcherVtk.NotifyFilter = System.IO.NotifyFilters.FileName |  //文件名
                    System.IO.NotifyFilters.DirectoryName |  // 目录名
                    System.IO.NotifyFilters.Size            // 文件或文件夹的大小
                    | System.IO.NotifyFilters.Attributes |   // 文件或文件夹的特性
                    System.IO.NotifyFilters.LastWrite |      // 上一次向文件或文件夹写入内容的日期
                    System.IO.NotifyFilters.LastAccess |     // 文件或文件夹上一次打开的日期
                    System.IO.NotifyFilters.CreationTime |   // 文件或文件夹的创建时间
                    System.IO.NotifyFilters.Security;        // 文件或文件夹的安全设置
            }
            
            if (m_timer == null && (watcherJson != null || watcherVtk != null))
            {
                int sss = 20000;
                sss = int.TryParse(TimeoutMillis, out sss) ? sss : 20000;
                //设置定时器的回调函数。此时定时器未启动
                m_timer = new System.Threading.Timer(new System.Threading.TimerCallback(OnWatchedFileChange), this, 0, sss);
            }
        }


        void OnProcessChanged(object sender, System.IO.FileSystemEventArgs e)
        {
            //获取文件变更的类型
            var changtype = GetChangeType(e.ChangeType);
           
            System.Threading.Mutex mutex = new System.Threading.Mutex(false, "FSW");
            mutex.WaitOne();
            ChangeInfo info = new ChangeInfo();
            info.Name = e.Name;
            info.FullPath = e.FullPath;
            
            if (e.ChangeType != System.IO.WatcherChangeTypes.Deleted)
            {
                bool IsExists = false;//当前文件是否在变更集合中
                for (int i = 0; i < files.Count; i++)
                {
                    if (files[i].Name == info.Name && files[i].FullPath == info.FullPath)
                    {
                        IsExists = true;
                        files[i].LastTime = DateTime.Now;
                        break;
                    }
                }
                if (!IsExists)
                {
                    info.LastTime = DateTime.Now;
                    files.Add(info);
                    LogHelper.GetInstance().Info(string.Format("OnProcessChanged 文件【{0}】加入待处理队列",  e.FullPath));
                }
            }
            else
            {
                files = files.Where(aa => aa.Name != info.Name && aa.FullPath != info.FullPath).ToList();
                LogHelper.GetInstance().Info(string.Format("OnProcessChanged 文件【被删除】名称【{0}】路径{1}", e.Name, e.FullPath));
            }
            mutex.ReleaseMutex();
        }

通过计时器处理文件转移


        private void OnWatchedFileChange(object state)
        {
            lock (timeLock)
            {
                int ss = 120;
                ss = int.TryParse(ChangedTime, out ss) ? ss : 120;
                var tempList = files.Where(aa => (DateTime.Now - aa.LastTime).TotalSeconds > ss).ToList();
                backup.AddRange(tempList);
                for (int i = 0; i < tempList.Count(); i++)
                {
                    files.Remove(tempList[i]);
                }
                LogHelper.GetInstance().Debug(string.Format("变更文件待处理数量【{0}】即将处理数量【{1}】!", files.Count, backup.Count));

                if (backup.Count > 0)
                {
                    //输出obj路径
                    if (!OutPutPath.Last<char>().Equals('\\'))
                    {
                        OutPutPath = OutPutPath + "\\";
                    }
                    string newfilename = "";//对文件进行重命名
                    string filePathOnly = "";//D:\Temp
                    string folderName = "";//当前文件对应的父级文件夹
                    string copypath = "";//输出的目标路径
                    List<int> arry = new List<int>();
                    int index = 0;
                    foreach (ChangeInfo file in backup)
                    {
                        try
                        {
                            newfilename = file.Name.Replace("\\", "_");//对文件重命名
                            filePathOnly = System.IO.Path.GetDirectoryName(file.FullPath);  //D:\Temp
                            folderName = System.IO.Path.GetFileName(filePathOnly);//当前文件对应的父级文件夹
                            copypath = OutPutPath + folderName + "\\" + newfilename.Substring(0, newfilename.LastIndexOf('.'))+"\\";
                            if (!System.IO.Directory.Exists(copypath))
                            {
                                //创建输出目录
                                System.IO.Directory.CreateDirectory(copypath);
                            }

                            if (System.IO.File.Exists(file.FullPath))
                            {
                                //复制原始数据文件
                                System.IO.File.Copy(file.FullPath, copypath + newfilename, true);
                                LogHelper.GetInstance().Debug(string.Format("路径【{0}】已复制到【{1}】重命名为【{2}】", file.FullPath, copypath, newfilename));
                            }
                            else {
                                LogHelper.GetInstance().Debug(string.Format("文件【{0}】不存在", file.FullPath, copypath, newfilename));
                            }
                            arry.Add(index);
                            index++;
                        }
                        catch (Exception ex)
                        {
                            LogHelper.GetInstance().Debug(string.Format("路径【{0}】复制失败:{1}",file.FullPath, ex.Message));
                        }
                    }
                    for (int i = arry.Count; i > 0; i--)
                    {
                        backup.Remove(backup[i - 1]);
                    }
                    LogHelper.GetInstance().Debug(string.Format("变更文件待处理数量【{0}】剩余处理数量【{1}】本次处理【{2}】!", files.Count, backup.Count, arry.Count));
                }
            }
        }

根据变更的参数获取变更描述


        private string GetChangeType(System.IO.WatcherChangeTypes watcherChangeTypes)
        {
            string str = "";
            switch (watcherChangeTypes)
            {
                case System.IO.WatcherChangeTypes.Created:
                    str = "新建";
                    break;
                case System.IO.WatcherChangeTypes.Deleted:
                    str = "删除";
                    break;
                case System.IO.WatcherChangeTypes.Changed:
                    str = "更改";
                    break;
                case System.IO.WatcherChangeTypes.Renamed:
                    str = "重命名";
                    break;
                case System.IO.WatcherChangeTypes.All:
                    str = "创建、删除、更改或重命名";
                    break;
                default:
                    str = "未知状态";
                    break;

            }
            return str;
        }

变更文件对象

    public class ChangeInfo
    {
        public string Name { get; set; }
        public string FullPath { get; set; }
        public DateTime LastTime { get; set; }
    }

程序调用方法

        FileWatcher(fileTypeJson);
        FileWatcher(fileTypeVtk);

另外,如果在程序关闭期间文件变更,则无法知晓。可通过记录程序退出时间,对退出后修改的文件进行筛选。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值