using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace Misc
{
///
///
/// 用于备份!!!
/// 流程:
///
/// 系统启动:
///
/// BackupFile.Add("profile.xml", func_isFileOK);
/// BackupFile.Add("initparam.xml", func_isFileOK);
/// BackupFile.Add("renzijiascan.xml", func_isFileOK);
///
/// CheckResult cr = BackupFile.Check()//检测,并处理
/// switch(cr)//根据结果显示在界面
///
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;
}
///
/// 恢复所有文件 (调取 backup 文件夹 内的文件出来)
///
///
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;
}
}
}
///
/// 路径, 文件名
///
static List fileinfos = new List();
static BackupFile()
{
}
///
/// 加入需要备份的文件路径
///
///
///
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
{
///
/// 文件都没问题
///
OK,
///
/// 文件有问题,已经成功恢复
///
RESTORE,
///
/// 文件有问题, 恢复不成功
///
ERR_RESTORE
}
///
/// 检测 文件 是否完整,;完整则备份;有问题,还原
///
///
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;
}
///
/// 文件都完整, 备份 所有文件 (备份到 backup 文件夹)
///
public static void Backup()
{
foreach (FileInfo fi in fileinfos)
{
fi.Backup();
}
}
///
/// 恢复所有文件 (调取 backup/ 文件夹 内的文件出来)
///
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;
}
}
}