using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace Misc { /// <summary> /// /// 用于备份!!! /// <para>流程:</para> /// /// <para>系统启动:</para> /// /// <para>BackupFile.Add("profile.xml", func_isFileOK);</para> /// <para>BackupFile.Add("initparam.xml", func_isFileOK);</para> /// <para>BackupFile.Add("renzijiascan.xml", func_isFileOK);</para> /// <para /> /// <para>CheckResult cr = BackupFile.Check()//检测,并处理</para> /// <para>switch(cr)//根据结果显示在界面</para> /// </summary> public class BackupFile { public delegate bool IsFileOKHandler(string filepath); class FileInfo { public int groupno; public string Path; public string FileName; public IsFileOKHandler func_isFileOK; public bool hasCheck = false; public CheckResult cr = CheckResult.OK; public void Backup() { hasCheck = true; if (!Directory.Exists("backup")) Directory.CreateDirectory("backup"); if (File.Exists(Path)) { string sourceFileName = Path; string destFileName = @"backup\" + FileName; System.IO.FileInfo fi_s = new System.IO.FileInfo(sourceFileName); System.IO.FileInfo fi_d = new System.IO.FileInfo(destFileName); if (fi_d.Exists) { if (fi_d.LastWriteTime == fi_s.LastWriteTime) //文件已经备份了,跳过 return; } //他们有一样的LastWriteTime File.Copy(sourceFileName, destFileName, true); } cr = CheckResult.OK; } /// <summary> /// 恢复所有文件 (调取 backup 文件夹 内的文件出来) /// </summary> /// <returns></returns> public bool Restore() { hasCheck = true; if (!Directory.Exists("backup")) { cr = CheckResult.ERR_RESTORE; return false; } try { string destFileName = Path; string sourceFileName = @"backup\" + FileName; if (File.Exists(sourceFileName)) { //他们有一样的LastWriteTime File.Copy(sourceFileName, destFileName, true); cr = CheckResult.RESTORE; return true; } else { cr = CheckResult.ERR_RESTORE; return false; } } catch { cr = CheckResult.ERR_RESTORE; return false; } } } /// <summary> /// 路径, 文件名 /// </summary> static List<FileInfo> fileinfos = new List<FileInfo>(); static BackupFile() { } /// <summary> /// 加入需要备份的文件路径 /// </summary> /// <param name="path"></param> /// <param name="func_isFileOK"></param> public static void Add(string path, IsFileOKHandler func_isFileOK) { Add(-1, path, func_isFileOK); } public static void Add(int groupno, string path, IsFileOKHandler func_isFileOK) { if ((from fi in fileinfos where fi.Path == path select fi).Count() > 0)//已经存在 return; string filename = System.IO.Path.GetFileName(path); string fn = filename; //当已经有重名,在这个名字后面加数字。 int i = 1; bool b; while (true) { b = (from fi in fileinfos where fi.FileName == fn select fi).Count() > 0; if (b == true) { fn = filename + i.ToString(); i++; } else { break; } } fileinfos.Add( new FileInfo() { groupno = groupno, FileName = fn, Path = path, func_isFileOK = func_isFileOK }); } public static bool xml_isFileOK (string p) { try { System.Xml.Linq.XElement root = System.Xml.Linq.XElement.Load(p); return true; } catch (Exception e) { return false; } } public static bool csv_isFileOK(string p) { try { //System.Xml.Linq.XElement root = System.Xml.Linq.XElement.Load(p); //第1行 必须找一个逗号 using (StreamReader sw = new StreamReader(p, Encoding.GetEncoding("GB2312"))) { while (!sw.EndOfStream) { string item; item = sw.ReadLine(); if (item.Contains(',')) return true; else return false; } } return false; } catch (Exception e) { return false; } } public enum CheckResult { /// <summary> /// 文件都没问题 /// </summary> OK, /// <summary> /// 文件有问题,已经成功恢复 /// </summary> RESTORE, /// <summary> /// 文件有问题, 恢复不成功 /// </summary> ERR_RESTORE } /// <summary> /// 检测 文件 是否完整,;完整则备份;有问题,还原 /// </summary> /// <returns></returns> public static CheckResult Check() { foreach (FileInfo fi in fileinfos) { if(fi.hasCheck) continue; //找到同组的其它fi if (fi.groupno != -1) { var v = from fi1 in fileinfos where fi1.groupno == fi.groupno select fi1; if (v.All(fi1 => (fi1.func_isFileOK != null) && (fi1.func_isFileOK(fi1.Path)))) { //没问题,备份 foreach (FileInfo fi1 in v) fi1.Backup(); } else { //其中一个有问题, 同组的全部还原 foreach (FileInfo fi1 in v) fi1.Restore(); } } else { if (fi.func_isFileOK(fi.Path)) { //没问题,备份 fi.Backup(); } else { //有问题, 还原 fi.Restore(); } } } if (fileinfos.All(fi => fi.cr == CheckResult.OK)) return CheckResult.OK; else if (fileinfos.Any(fi => fi.cr == CheckResult.ERR_RESTORE)) return CheckResult.ERR_RESTORE; else return CheckResult.RESTORE; } /// <summary> /// 文件都完整, 备份 所有文件 (备份到 backup 文件夹) /// </summary> public static void Backup() { foreach (FileInfo fi in fileinfos) { fi.Backup(); } } /// <summary> /// 恢复所有文件 (调取 backup/ 文件夹 内的文件出来) /// </summary> public static bool Restore() { foreach (FileInfo fi in fileinfos) { fi.Restore(); } if (fileinfos.Any(fi => fi.cr == CheckResult.ERR_RESTORE)) return false; else return true; } } }