using Oreo.FileMan.Commons; using Oreo.FileMan.DatabaseEngine; using Oreo.FileMan.Models; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using Y.Utils.DataUtils.Collections; using Y.Utils.DataUtils.DateTimeUtils; using Y.Utils.IOUtils.FileManUtils; using Y.Utils.IOUtils.FileUtils; using Y.Utils.IOUtils.PathUtils; namespace Oreo.FileMan.Services { public class FileBackupService { public List Paths = new List();//要备份的文件夹 private FileWatcher Watcher = new FileWatcher(null);//文件监视器 private List BackupFiles = new List();//当前要备份的文件任务 public bool IsStart = false; public bool StatusOfReadBackupPaths = false; public int FileCount { get { return _FileCount; } } private int _FileCount = 0; public void Start() { if (!IsStart) { IsStart = true; Watcher.EventHandler += WatcherChangedEvent; Watcher.Start();//启动文件变动监听 Task.Factory.StartNew(() => { ReadBackupFileCount();//读取备份文件总数 ReadBackupPaths();//读取备份文件夹列表 StatusOfReadBackupPaths = true; if (ListTool.HasElements(Paths)) { foreach (var p in Paths) { DefaultBackupFile(p.Path);//常规检查备份 } } BackupFileTask();//开始定时备份任务 }); } } public void Stop() { if (IsStart) { IsStart = false; } } /// /// 文件发生变动事件 /// /// /// private void WatcherChangedEvent(object sender, FileWatcherEventArgs e) { AddToBackupFiles(e.FullPath); } /// /// 定时处理要备份的文件任务 /// private void BackupFileTask() { while (IsStart) { if (ListTool.HasElements(BackupFiles)) { //获取要备份的文件列表并复制样本 List temp; lock (BackupFiles) { temp = BackupFiles; BackupFiles = new List(); } using (var db = new Muse()) { foreach (var t in temp) { //要备份的文件存在 if (File.Exists(t)) { //文件属于要备份的文件目录 string filepath = DirTool.GetFilePath(t); BackupPaths path = Paths.FirstOrDefault(x => filepath.Contains(x.Path)); if (path != null) { //文件的MD5码以前没有备份过 string md5 = FileTool.GetMD5(t); bool isback = db.Any(x => x.FullPath == t && x.Md5 == md5, null); if (!isback) { string pathname = path.Path;//备份文件夹路径 string pathalias = path.Alias;//备份文件夹别名 string pathfile = t.Substring(pathname.Length, t.Length - pathname.Length);//截取备份文件子目录(相对备份文件夹) string fileext = "." + DateTimeConvert.CompactString(DateTime.Now) + Path.GetExtension(t);//设置后缀 string fullpath = DirTool.Combine(R.Settings.FileBackup.FileManBackup, pathalias, pathfile + fileext);//组合路径 //删除冗余 DeleteExcess(t); //备份文件 BackupFile(t, fullpath, md5); _FileCount++; } } } } } } Thread.Sleep(R.Settings.FileBackup.BACK_UP_INTERVAL); } } /// /// 读取备份文件总数 /// private void ReadBackupFileCount() { //统计备份文件总数 using (var db = new Muse()) { _FileCount = db.Do().Count(); } } /// /// 读取备份文件夹列表 /// private void ReadBackupPaths() { //读取要备份的文件路径列表 using (var db = new Muse()) { Paths = db.GetAll(null, false).ToList(); if (ListTool.HasElements(Paths)) { foreach (var p in Paths) { AddToWatcherPath(p.Path); } } } } /// /// 初始读取文件并备份 /// public void DefaultBackupFile(string path) { //读取本地文件夹中的所有文件列表 List files = FileTool.GetAllFile(path); if (ListTool.HasElements(files)) { foreach (var file in files) { try { string lastwritetime = DateTimeConvert.StandardString(File.GetLastWriteTime(file)); using (var db = new Muse()) { BackupFiles backfile = db.Get(x => x.FullPath == file && x.LastWriteTime == lastwritetime, null); if (backfile == null) AddToBackupFiles(file); } } catch (Exception e) { } } } } /// /// 添加要备份的文件到备份计划列表 /// /// private void AddToBackupFiles(string fullpath) { if (Paths.Any(x => fullpath.Contains(x.Path))) { //变动的是文件且文件存在 if (FileTool.IsFile(fullpath)) { //添加到备份列表 if (!BackupFiles.Contains(fullpath)) BackupFiles.Add(fullpath); //UIDgvFileAdd(e.Name, e.FullPath, e.ChangeType.ToString()); } } } /// /// 添加要备份的文件夹 /// /// public void AddToWatcherPath(string path) { Watcher.AddPath(path);//添加要备份的文件夹 DefaultBackupFile(path);//常规检查备份文件夹 } /// /// 删除超过备份最大次数的项 /// private void DeleteExcess(string path) { using (var db = new Muse()) { int count = db.Do().Count(x => x.FullPath == path); if (count >= R.Settings.FileBackup.BACK_UP_COUNT) { var fs = db.Gets(x => x.FullPath == path, null).OrderBy(x => x.Id).ToList(); if (ListTool.HasElements(fs)) { for (int i = 0; i <= count - R.Settings.FileBackup.BACK_UP_COUNT; i++) { try { File.Delete(fs[i].BackupFullPath); db.Del(fs[i], true); } catch (Exception e) { } } } } } } /// /// 备份文件 /// /// /// private void BackupFile(string path, string newpath, string md5) { using (var db = new Muse()) { try { if (DirTool.Create(DirTool.GetFilePath(newpath))) { string lastwritetime = DateTimeConvert.StandardString(File.GetLastWriteTime(path)); File.Copy(path, newpath, true); db.Add(new BackupFiles() { FullPath = path, BackupFullPath = newpath, Size = FileTool.Size(path), BackupTime = DateTimeConvert.StandardString(DateTime.Now), LastWriteTime = lastwritetime, Md5 = md5, }); } } catch (Exception e) { } } } } }