65.9K
CodeProject 正在变化。 阅读更多。
Home

备份实用程序

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.11/5 (12投票s)

2008年11月20日

CPOL

1分钟阅读

viewsIcon

48116

downloadIcon

2409

一个简单的 OO 备份实用程序,可以保留完整的文件路径。

main.PNG

引言

这个小工具是为工作开发的,以便在运行新的部署之前备份部署位置(DEV、QA、PROD)。它很好地完成了它的目的,并且多次拯救了我和我的同事。以下是一些亮点:

  • 面向对象设计
  • UI线程
  • 能够备份网络位置的文件
  • 使用 XML 备份集
  • 保留完整的文件位置

options_general.PNG

备份集选项。设置名称、描述以及备份文件将被保存的位置。

options_directories.PNG

备份集选项。在这里添加要备份的目录。由于内置文件浏览器不允许添加网络位置,因此需要键入或复制和粘贴目录。

可序列化的 BackupSetInfo 类型

[Serializable]
public class BackupSetInfo
{
  private string BackupDescriptionField;

  private string BackupNameField;

  private List<string> BackupDirectoriesField;

  private string BackupToDirectoryField;

  public string BackupDescription
  {
    get { return BackupDescriptionField; }
    set { BackupDescriptionField = value; }
  }

  public string BackupName
  {
    get { return BackupNameField; }
    set { BackupNameField = value; }
  }

  public List<string> BackupDirectories
  {
    get { return BackupDirectoriesField; }
    set { BackupDirectoriesField = value; }
  }

  public string BackupToDirectory
  {
    get { return BackupToDirectoryField; }
    set { BackupToDirectoryField = value; }
  }

  public BackupSetInfo()
  {
    this.BackupDirectories = new List<string>();
  }
}

备份集通过将对象实例序列化到文件系统来保存。

public void Update(BackupSetInfo BackupSetInfoOf)
{
  bool isUpdate = false;
  for (int i = 0; i < this.ListOfBackupSetInfo.Count; i++)
  {
    if (this.ListOfBackupSetInfo[i].BackupName == BackupSetInfoOf.BackupName)
    {
      this.ListOfBackupSetInfo[i] = BackupSetInfoOf;
      isUpdate = true;
    }
  }
  if (!isUpdate)
    this.ListOfBackupSetInfo.Add(BackupSetInfoOf);

  SerializeXml(BackupSetInfoOf.BackupName.Replace(" ", "") + ".backupset", 
		typeof(BackupSetInfo), BackupSetInfoOf);
}

private void SerializeXml(string FileName, Type ObjectType, object InstanceToSerialize)
{
  File.Delete(FileName);
  using (FileStream fs = new FileStream
	(AppDomain.CurrentDomain.BaseDirectory + FileName, FileMode.Create))
  {
    using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(fs))
    {
      XmlSerializer serializer = new XmlSerializer(ObjectType);
      serializer.Serialize(writer, InstanceToSerialize);
    }
  }
}

备份集被反序列化,对象作为 ListOfBackupSetInfo 的一部分被加载。

public void LoadBackupSets()
{
  this.ListOfBackupSetInfo.Clear();
  foreach (string fullFile in Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory))
  {
    string[] fileArray = fullFile.Split(new char[] { '\\' });
    string file = fileArray[fileArray.GetUpperBound(0)];
    if (file.EndsWith(".backupset"))
    {
      BackupSetInfo si = (BackupSetInfo)DeserializeXml(file, typeof(BackupSetInfo));
      this.ListOfBackupSetInfo.Add(si);
    }
  }
}

private object DeserializeXml(string FileName, Type ObjectType)
{
  using (FileStream fs = new FileStream(FileName, FileMode.Open))
  {
    using (XmlDictionaryReader reader = 
	XmlDictionaryReader.CreateTextReader(fs, XmlDictionaryReaderQuotas.Max))
    {
      XmlSerializer serializer = new XmlSerializer(ObjectType);
      return serializer.Deserialize(reader);
    }
  }
}

备份使用递归复制方法执行。首先计算文件数量,以获得准确的进度条测量值。

private void CopyDirectory(DirectoryInfo Source, 
	DirectoryInfo Destination, bool CountOnly)
{
  foreach (FileInfo f in Source.GetFiles())
  {
    if (CountOnly)
      this.TotalFiles++;
    else
    {
      f.CopyTo(Destination + @"\" + f.Name);
      this.CopiedFiles++;
    }
  }
  foreach (DirectoryInfo dS in Source.GetDirectories())
  {
    string newDirPart = dS.FullName.Replace(Source.FullName, "");
    string newDestinationPath = Destination + newDirPart;
    DirectoryInfo dD = new DirectoryInfo(newDestinationPath);
    dD.Create();
    CopyDirectory(dS, dD, CountOnly);
  }
}

backup_progress.PNG

备份进度。备份在单独的线程上执行,以保持 UI 的响应。

public partial class frmProgress : System.Windows.Forms.Form
{
  Backup backup = new Backup();
  private BackupSetInfo settingsInfo = new BackupSetInfo();
  private static BackupResponseInfo response = new BackupResponseInfo();
  private Thread t;
  public delegate void BackupFinishedDelegate();

  public frmProgress(BackupSetInfo SettingsInfoOf)
  {
    InitializeComponent();
    settingsInfo = SettingsInfoOf;
  }

  private void ProcessError(Exception ex)
  {
    this.Cursor = Cursors.Arrow;
    MessageBox.Show(ex.Message + "\r\n" + ex.ToString());
  }

  private void btnDo_Click(object sender, System.EventArgs e)
  {
    timer1.Enabled = false;

    if (btnDo.Text.ToLower().StartsWith("cancel"))
      t.Abort();
    this.Close();
  }

  private void frmProgress_Load(object sender, System.EventArgs e)
  {
    t = new Thread(delegate() { BackupStart(this.settingsInfo); });
    t.Start();
    timer1.Enabled = true;
  }

  private void BackupStart(BackupSetInfo SettingsInfoOf)
  {
    response = backup.BackupFiles(SettingsInfoOf);
    
    this.Invoke(new BackupFinishedDelegate(BackupFinished));
  }

  private void BackupFinished()
  {
    lblStatus.Text = response.Message;
    btnDo.Text = "OK";
  }

  private void timer1_Tick(object sender, EventArgs e)
  {
    this.progressBar1.Maximum = backup.TotalFiles;
    if(backup.CopiedFiles<=progressBar1.Maximum)
      this.progressBar1.Value = backup.CopiedFiles;
  }
}

backup_files.PNG

备份的文件。test2 是此备份集的名称。它附加了日期和时间。如您所见,它保留了文件位置。

历史

  • 2008 年 11 月 20 日:版本 1
© . All rights reserved.