public class DataFileSystemWatcher
    {
        /// <summary>
        /// 程序启动
        /// </summary>
        public void StartProcess()
        {
            try
            {
                //启用监听,监听文件夹
                Run();
            }
            catch (Exception ex)
            {
                Log.WriteLog(LogFile.Error, "检查ECA文件夹时出错\r\n" + ex);
            }
        }
        /// <summary>
        /// 监听事件
        /// </summary>
        public static void Run()
        {
            FileSystemWatcher watcher = new FileSystemWatcher();
            //watcher.Path = AppDomain.CurrentDomain.BaseDirectory;
            watcher.Path = @"E:\Share\ecn汇总\ECA\";//监听路径
            /* 设置为监视 LastWrite 和 LastAccess 时间方面的更改,以及目录中文本文件的创建、删除或重命名。 */
            watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.CreationTime
               | NotifyFilters.FileName | NotifyFilters.DirectoryName;//NotifyFilters.LastAccess |
            // 只监控.xls文件
            watcher.Filter = "*.xls";

            // 添加事件处理器。
            watcher.Changed += new FileSystemEventHandler(OnChanged);
            watcher.Created += new FileSystemEventHandler(OnChanged);
            watcher.Deleted += new FileSystemEventHandler(OnChanged);
            watcher.Renamed += new RenamedEventHandler(OnRenameed);

            // 开始监控。
            watcher.EnableRaisingEvents = true;
        }



        /// <summary>
        /// 文件改变事件,增删改
        /// </summary>
        /// <param name="source"></param>
        /// <param name="e"></param>
        public static void OnChanged(object source, FileSystemEventArgs e)
        {
            try
            {
                //根据路径去顶那些文件发生修改
                switch (e.ChangeType)
                {
                    case WatcherChangeTypes.Created://新建文件
                        GetExcelData(e.FullPath, e.Name, 0, null);//具体处理逻辑
                        break;

                    case WatcherChangeTypes.Deleted://文件删除
                        GetExcelData(e.FullPath, e.Name, 2, null);//具体处理逻辑
                        break;

                    case WatcherChangeTypes.Changed://文件修改
                        GetExcelData(e.FullPath, e.Name, 1, null);//具体处理逻辑
                        break;

                    default:
                        break;
                }
            }
            catch (Exception ex)
            {
                Log.WriteLog(LogFile.Error, "监听的OnChanged出错,出错类型" + e.ChangeType + "\r\n" + ex);
            }
        }

        /// <summary>
        /// 重命名事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void OnRenameed(object sender, RenamedEventArgs e)
        {
            try
            {
                //更新数据库
                string md5_new = GetMD5HashFromFile(e.FullPath);//新MD5
                //根据原来的路径和文件名,获取文件
                ECAInfo info_dele = new BaseLink().SelectECAInfo(e.OldFullPath, e.OldName);
                //更新数据
                if (info_dele != null)
                {
                    info_dele.ECAPath = e.FullPath;
                    info_dele.ECAName = e.Name;
                    new BaseLink().RenameECAInfo(info_dele,out string msg);//具体处理逻辑
                    Log.WriteLog(LogFile.Info, e.OldName + "重命名为->" + e.Name + msg);
                }
            }
            catch (Exception ex)
            {
                Log.WriteLog(LogFile.Error, "文件发生重命名事件出错\r\n" + ex);
            }
        }

        /// <summary>
        /// 获取文件MD5值
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        private static string GetMD5HashFromFile(string filePath)
        {
            try
            {
                FileStream file = new FileStream(filePath, FileMode.Open);
                System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
                byte[] retVal = md5.ComputeHash(file);
                file.Close();

                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < retVal.Length; i++)
                {
                    sb.Append(retVal[i].ToString("x2"));
                }
                return sb.ToString();
            }
            catch (Exception ex)
            {
                Log.WriteLog(LogFile.Error, "获取文件MD5值出错\r\n" + ex);
                return "";
            }
        }

        }

    }

 

上面只是之前找到的一种方案,后来找到一个更好的方法.可以执行多个监听,同时也弄清楚了一些问题,分享一下:先上代码:

FileSystemWatcher[] fswArr;

        private delegate void setLogTextDelegate(FileSystemEventArgs e);

        private delegate void renamedDelegate(RenamedEventArgs e);

        /// <summary>
        /// 开始按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void start_tsbtn_Click(object sender, EventArgs e)
        {
            if (this.spcifiedFloder_rbtn.Checked)//指定文件
            {
                if (!string.IsNullOrEmpty(this.filePath_txt.Text))//文件路径
                {
                    fswArr = new FileSystemWatcher[1];

                    fswArr[0] = new FileSystemWatcher();

                    fswArr[0].Path = this.filePath_txt.Text;  //设置监控路径

                    fswArr[0].IncludeSubdirectories = this.subDirWatcher_chk.Checked;  //获取或设置一个值,该值指示是否监视指定路径中的子目录。

                    fswArr[0].NotifyFilter = NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.Size;

                    fswArr[0].Created += new FileSystemEventHandler(this.fileSystemWatcher_EventHandle);

                    fswArr[0].Deleted += new FileSystemEventHandler(this.fileSystemWatcher_EventHandle);

                    fswArr[0].Changed += new FileSystemEventHandler(this.fileSystemWatcher_EventHandle);

                    fswArr[0].Renamed += new RenamedEventHandler(this.fileSystemWatcher_Renamed);

                    fswArr[0].EnableRaisingEvents = true;
                }
                else              
                {
                    MessageBox.Show("请先选择监控路径!");

                    return;
                }

            }
            else
            {
                int checkedCount = this.dir_lvw.CheckedItems.Count;//选择的多个监听路径

                if (checkedCount > 0)
                {
                    fswArr = new FileSystemWatcher[checkedCount];

                    for (int i = 0; i < this.dir_lvw.CheckedItems.Count; i++)
                    {
                        fswArr[i] = new FileSystemWatcher();

                        fswArr[i].Path = this.dir_lvw.CheckedItems[i].Text;

                        fswArr[i].IncludeSubdirectories = this.subDirWatcher_chk.Checked;  //获取或设置一个值,该值指示是否监视指定路径中的子目录。

                        fswArr[i].NotifyFilter = NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.Size;

                        fswArr[i].Created += new FileSystemEventHandler(this.fileSystemWatcher_EventHandle);

                        fswArr[i].Deleted += new FileSystemEventHandler(this.fileSystemWatcher_EventHandle);

                        fswArr[i].Changed += new FileSystemEventHandler(this.fileSystemWatcher_EventHandle);

                        fswArr[i].Renamed += new RenamedEventHandler(this.fileSystemWatcher_Renamed);

                        fswArr[i].EnableRaisingEvents = true;

                    }
                }
                else
                {
                    MessageBox.Show("您尚未选择任何监控路径!");

                    return;
                }
            }
        }

        /// <summary>
        /// 停止按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void stop_tsbtn_Click(object sender, EventArgs e)
        {
            foreach (FileSystemWatcher fsw in fswArr)
            {
                fsw.EnableRaisingEvents = false; //获取或设置一个值,该值指示是否启用此组件。
            }
        }


        /// <summary>
        /// 文件监听事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void fileSystemWatcher_EventHandle(object sender, FileSystemEventArgs e)
        {
            if (this.fileEventLog_lvw.InvokeRequired)
            {
                this.fileEventLog_lvw.Invoke(new setLogTextDelegate(setLogText), new object[] { e });
            }
        }

        /// <summary>
        /// 重命名事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void fileSystemWatcher_Renamed(object sender,RenamedEventArgs e)
        {
            if (this.fileEventLog_lvw.InvokeRequired)
            {
                this.fileEventLog_lvw.Invoke(new renamedDelegate(setRenamedLogText), new object[] { e });
            }
        }

        private void setLogText(FileSystemEventArgs e)
        {
            //Todo
        }

        private void setRenamedLogText(RenamedEventArgs e)
        {
            //Todo
        }

总结:

1.有些时候只想监听文件发生修改的动作,但是有些时候文件修改了会触发好几次监听动作。后来发现这个和 设置的NotifyFilter 属性有关,上文中第二种方法中的 NotifyFilter 属性设置成,NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.Size就不会出现这种问题,但是如果再加上LastWriteTime这个属性,那么就会触发多次修改。因为之前监听到的是文件Size的变化事件,保存动作完成后会触发LastWriteTime事件,所以才会有多次触发。因此,监听的类型不是越多越好,要根据自己的实际需求进行选择