目录
介绍
备份架构
演示程序
程序源代码
- 下载源代码 - 83 KB
CopyTree是一个实现备份轮换方案的备份实用程序。它是一个用C#编写的开源Windows窗体应用程序。该实用程序旨在将关键文件夹备份到多个备份文件夹。运行该实用程序的结果是每个备份文件夹在给定时间是源文件夹的精确副本。每次运行该实用程序时,将使用当前源文件夹更新最旧的备份文件夹。换句话说,该实用程序在备份文件夹之间轮换。备份更新过程可确保备份目录结构与源目录相同。新文件从源复制到备份。已删除的文件将从备份中删除。已修改的文件将复制旧版本。未修改的文件将被忽略。除了第一次,
安装该实用程序后,您可以选择硬盘上的关键文件夹进行备份。我们将它们称为源文件夹。接下来,在外部硬盘驱动器上创建多个备份文件夹。我的选择是三个备份文件夹。每次运行该实用程序时,它都会将源文件夹备份到最早的这些备份文件夹中。结果是,您可以随时拥有源代码文件夹的三代副本。例如,如果您在一天结束时每天运行一次该实用程序,那么在第二天您将获得昨天,前天和前三天的副本。
复制过程将源文件夹结构与备份文件夹结构进行比较。如果源中存在文件或子文件夹且备份中不存在该文件或子文件夹,则该实用程序会将其从源复制到备份。如果备份中存在文件或子文件夹且源中不存在该文件或子文件夹,则该实用程序会从备份中删除该文件或子文件夹。如果源和备份中都存在文件,则该实用程序会比较源和备份的LastWriteTimeUtc文件。如果它们相等,则该实用程序假定自上次备份以来未修改该文件且未进行任何复制。如果上次写入时间不同,则实用程序将复制源文件并覆盖旧备份。
文件复制过程保留文件CreationTimeUtc,LastWriteTimeUtc和LastAccessTimeUtc。此外,文件属性标志:ReadOnly,Hidden,System,Archive和Normal将被保留。如果文件是只读的,并且需要删除它或覆盖它,则只删除只读标志。无法复制计算机上其他应用程序正在使用的源文件。异常将被try- catch对绑定,并将显示和记录错误消息。备份过程将继续。
备份架构备份架构由两个列表组成。备份列表和源列表。每个列表由记录组成,每个记录包含两个字段。
- 备份根文件夹
- 上次备份日期和时间
- 备份根文件夹名称
- 备份子文件夹名称和源文件夹路径
- 备份子文件夹名称
- 源文件夹路径
下面,您将找到备份根文件夹列表的示例。该列表由外部硬盘驱动器G:上的三代备份轮换组成。
- 2018/01/01 17:12:20 G:\ Backup1
- 2018/01/02 17:35:43 G:\ Backup2
- 2018/01/03 18:01:05 G:\ Backup3
我们假设您要备份存储在文件夹C:\ MyDevelopment中的开发项目。并且您想要备份您的私人文档文件夹C:\ MyDocuments。该备份子文件夹名称和源文件夹路径将是:
- MyDevelopment C:\MyDevelopment
- MyDocuments C:\MyDocuments
如果Backup1选择作为当前备份,则CopyTree树将C:\MyDevelopment复制到G:\ Backup1\MyDevelopment文件夹。并且C:\MyDocuments到G:\Backup1\MyDocuments。
CopyTree主界面
CopyTree编辑架构界面
演示程序在硬盘上创建一个文件夹CopyTree(或任何其他名称)。将CopyTree.exe复制到此文件夹。启动该程序。单击Edit Schema按钮。
将显示“编辑备份架构”窗体表单。添加一个或多个备份根文件夹。我的建议是三个。将建议的上次备份时间保留为当前时间。
添加一个或多个源文件夹路径及其相应的备份子文件夹。
单击保存。
如果所需的备份根目录结构不存在,CopyTree将请求您允许它来创建。
按“执行”执行备份。
备份进度将显示在屏幕顶部的信息文本标签中。
屏幕中央的错误日志将显示错误。通常,不会有错误。系统异常的最常见原因是尝试在文件使用时复制文件。
备份完成后,您可以按“查看日志”按钮或“查看错误”按钮查看所有活动。
程序源代码Backup类是实用程序的心脏。该backup类使用BackgroundWorker类在后台线程中运行实际的备份进程。
CopyTree类展示了如何创建Backup类,如何启动备份,如何将结果记录,以及如何在过程完成时得到通知。
创建backup类并附加两个事件处理程序。
// create backup class
Backup Backup = new Backup();
Backup.WriteToLogFile += WriteToLogFile;
Backup.BackupCompletedEvent += OnBackupCompleted;
定义写入日志文件事件处理程序。
///
/// Write to log file
///
/// Log or Error
/// Message
private void WriteToLogFile
(
LogControl Control, // LogControl is either Log or Error
string LogText // text
)
{
// write to loe and error files
}
定义备份完成事件处理程序。
///
/// Backup process is completed
///
private void OnBackupCompleted
(
bool BackupDone // true=normal completion, false=user pressed cancel
)
{
// perform completed event tasks
}
初始化备份。
// set the selected index of the backup folder list
Schema.RootIndex = SelectedIndex;
// initiate backup
Backup.BackupFolders(Schema);
Backup类的主要方法是PerformFolderBackup。它是遍历源和备份文件夹树的递归方法。
///
/// recursive folder backup
///
/// Source folder name
/// Backup folder name
private void PerformFolderBackup
(
DirectoryInfo SourceFolderInfo,
DirectoryInfo BackupFolderInfo
)
{
// cancel backup
if(BackupWorker.CancellationPending) throw new CanceBackupException();
// backup folder full name shortcut
string BackupFolderFullName = BackupFolderInfo.FullName;
// get source child files
FileInfo[] SourceFiles = SourceFolderInfo.GetFiles();
// get backup child files
FileInfo[] BackupFiles = BackupFolderInfo.GetFiles();
// source has files
if(SourceFiles.Length != 0)
{
// backup has files
if(BackupFiles.Length != 0)
{
// backup has files
EqualizeFiles(SourceFiles, BackupFiles, BackupFolderFullName);
}
// backup has no files
else
{
// copy all source files to backup folder
CopyFiles(SourceFiles, BackupFolderFullName);
}
}
// source has no files but backup has files
else if(BackupFiles.Length != 0)
{
// delete all files of backup folder
DeleteFiles(BackupFiles);
}
// get source child folders
DirectoryInfo[] SourceFolders = SourceFolderInfo.GetDirectories();
// get backup child folders
DirectoryInfo[] BackupFolders = BackupFolderInfo.GetDirectories();
// source has folders
if(SourceFolders.Length != 0)
{
// backup has folders
if(BackupFolders.Length != 0)
{
// backup has folders
EqualizeFolders(SourceFolders, BackupFolders, BackupFolderFullName);
}
// backup has no folders
else
{
// copy all source child folders to backup folder
CreateFolders(SourceFolders, BackupFolderFullName);
}
}
// source has no folders but backup has folders
else if(BackupFolders.Length != 0)
{
// delete all files of backup folder
DeleteFolders(BackupFolders);
}
// done
return;
}
原文地址:https://www.codeproject.com/Articles/1223887/Backup-Utility-implementing-Backup-Rotation-Scheme