/// <summary> /// 将文件系统信息插入到数据库 /// </summary> public static void BackupFSWithoutCheck(monitorServer ms, FileListenResolver flr) { DirectoryInfo targetDirInfo = new DirectoryInfo(ms.monitorLocalPath); //遍历文件列表 foreach (var targetFileInfo in targetDirInfo.EnumerateFiles("*", SearchOption.AllDirectories)) { bool isOk = false; /*此处向flr发送自制消息 * * targetFileInfo.FullName.Substring(0, targetFileInfo.FullName.LastIndexOf('\\')) 是为了保留完整路径信息 * 默认情况下.net将怪异的路径修正,造成文件找不到 */ string fullPath = FSUtil.GetFullPath(targetDirInfo); again : isOk = flr.OnProcess(new FileSystemEventArgs(WatcherChangeTypes.Created, ms.monitorLocalPath, fullPath.Substring(ms.monitorLocalPath.Length + 1))); if (!isOk) { //由于文件过多,需要等待一下 System.Threading.Thread.Sleep(2000); goto again; } } }
/// <summary> /// 放弃此 处理 /// </summary> private void FileCheck(monitorServer ms, FileListenResolver flr) { try { #region 维护文件列表数据 try { //判断数据库中对应monitorServer是否为空,如果为空 则不进行比较,直接插入 FileListenService fls = new FileListenService(); if (fls.IsDBCleared(ms.id)) { FileListenHelper.BackupFSWithoutCheck(ms, flr); } else { /** * 数据库数据正确性及完整性维护逻辑 20140706 xiecongwen * 进行比较 此处将不使用自制消息,即数据完整性交由数据库实现 * 为了提高效率:特将比较逻辑移到内存,即从数据库中取一部分数据 * 与文件系统进行比较 看是否存在 * * 两边数据相同:1.文件系统没有的,数据库要删除;文件系统有的,数据库要添加 * * 难点:查找文件是否在数据库中存在 原因:数据量大,且聚集为id * 从根目录开始: 1.目录下文件2.子目录 依次递归 */ } } catch (Exception ex) { logger.Error(MessageUtil.GetExceptionMsg(ex, "")); } #endregion } catch (Exception ex) { logger.Error(MessageUtil.GetExceptionMsg(ex, "")); } }
/// <summary> /// 具体业务逻辑 /// </summary> private void DO(CallBack action) { Signal.IsSystemStoping = false; try { Common.LogManager.WriteLog(LogFile.Bussiness, "Listen start"); //判断是否有监视JOB端(即MAC机) foreach (var ms in new DBService.MonitorServerService().GetMonitorServerListWithAttached()) { Common.LogManager.WriteLog(LogFile.Bussiness, ms.id + " attend to Listening"); #region 建立监视 try { DirectoryInfo targetDirInfo = new DirectoryInfo(ms.monitorLocalPath); #region 判断目标盘符是否有足够空间,并提示用户 //if (!FileListenHelper.CheckDisk(targetDirInfo)) //{ // new System.Threading.Thread(() => // { // //send mail // FileListenHelper.SendMail(targetDirInfo, ms); // }).Start(); //} #endregion //将当前已有文件系统信息同步到数据库,然后建立监控 /* * 由于时间原因,暂时认为此程序先开启,然后再开启BudFileListen 20140704 * * 当前逻辑是判断数据库中对应monitorserver是否为空 如果为空则扫描整个文件系统 * 并插入到数据库中 20140705 */ FileListenResolver flr = new FileListenResolver(ms); /** * * 20150104 xiecongwen filelisten表中只保存一个星期的,每个星期维护一次;如有不妥,可改为一个月 * 文件下载 主要查询pathBK */ //FileCheck(ms, flr); #region 设置监视器 FileSystemWatcher fsw = new FileSystemWatcher() { //只监听文件创建、删除、文件大小变化,忽略目录变化 NotifyFilter = NotifyFilters.Size | NotifyFilters.FileName, //Filter="*", Path = ms.monitorLocalPath, IncludeSubdirectories = true }; //设置事件 flr.SetEvent(fsw); fsw.EnableRaisingEvents = true; fswlist.Add(fsw); #endregion } catch (ArgumentException aex) { Common.LogManager.WriteLog(LogFile.Bussiness, ms.id + " error:" + aex.Message); //回调错误处理函数 if (action(aex)) { //用户选择退出时,当前线程直接退出,并新建一个线程去清理资源 ThreadPool.QueueUserWorkItem((x) => { Thread.Sleep(1000); ShutDown(); }); break; } continue; } catch (Exception ex) { logger.Error(ex.Message); action(ex); break; } //日志 通知 此monitorserver已经建立监听 Common.LogManager.WriteLog(LogFile.Bussiness, ms.id + " Listening"); #endregion } //开启定时同步线程 new System.Threading.Thread(() => SyncFileSystemAndDB()).Start(); //开启日志清理线程 new System.Threading.Thread(() => ClearOverdueLog()).Start(); } catch (Exception ex) { logger.Error(MessageUtil.GetExceptionMsg(ex, "")); action(ex); } finally { //所有server 都处理了 Common.LogManager.WriteLog(LogFile.Bussiness, "All servers have been processed"); } }