最近將客戶的一個ASP網站部署到了公司的機房雲服務器上,該ASP網站的文件總容量已有將近4GB。
雖然現在硬盤容量很大,但每天一次完整備份的話,那占用的硬盤空間會急劇上升,考慮一個更優的備份方案就是每天一次增量備份,每月一次完整備份。
於是就有了自己動手寫一個增量備份程序的念頭,雖然網上可能已經有了很多增量備份的程序,但為了更加靈活和能夠隨時適應項目的個性化要求,就決定使用winform寫一個備份程序。
代碼實現思路:
1、首先對需要備份的文件夾下的所有文件信息進行初始化,將所有文件的完整路徑及文件最后修改時間存儲到數據庫里(這里我采用的是SQLite數據庫)。
2、備份時遍歷文件夾下所有文件,然后通過文件的完整路徑對數據庫進行查詢,如果查詢不到數據,說明是新增的文件,這時就將文件復制到指定的備份目錄下,並且將文件信息插入數據庫;
如果查詢到數據,則對文件最后修改時間進行比較,如果時間不一致,就說明文件有改動,這時就將文件復制到指定的備份目錄下,並且將文件信息數據進行更新。
核心代碼如下:
class Bakuper { private static string srcPath = ConfigurationManager.AppSettings["srcPath"]; private static string destPath = ConfigurationManager.AppSettings["destPath"]; private static int fileCount; private static int copyCount; private static SQLiteConnection conn; public static int backupFile() { fileCount = 0; copyCount = 0; conn = SQLHelper.getSQLiteConnection(); DirectoryInfo theFolder = new DirectoryInfo(srcPath); readFolderList(theFolder); readFileList(theFolder); Console.WriteLine("共備份了" + copyCount+"個文件"); return copyCount; } static void readFolderList(DirectoryInfo folder) { DirectoryInfo[] dirInfo = folder.GetDirectories(); //遍歷文件夾 foreach (DirectoryInfo NextFolder in dirInfo) { readFolderList(NextFolder); readFileList(NextFolder); } } static void readFileList(DirectoryInfo folder) { FileInfo[] fileInfo = folder.GetFiles(); foreach (FileInfo NextFile in fileInfo) //遍歷文件 { SQLiteCommand cmd = new SQLiteCommand("select lastWriteTime from " + SQLHelper.TB_NAME + " where fullPath='" + NextFile.FullName + "'", conn); object obj = cmd.ExecuteScalar(); if (obj == null)//如果是新增的文件 { String fullname = folder.FullName; string newpath = fullname.Replace(srcPath, destPath + "\\" + DateTime.Now.ToString("yyyyMMdd")); DirectoryInfo newFolder = new DirectoryInfo(newpath); if (!newFolder.Exists) { newFolder.Create(); } NextFile.CopyTo(newpath + "\\" + NextFile.Name, true); SQLiteCommand cmdInsert = new SQLiteCommand(conn);//實例化SQL命令 cmdInsert.CommandText = "insert into " + SQLHelper.TB_NAME + " values(@fullPath, @lastWriteTime)";//設置帶參SQL語句 cmdInsert.Parameters.AddRange(new[] {//添加參數 new SQLiteParameter("@fullPath", NextFile.FullName), new SQLiteParameter("@lastWriteTime", NextFile.LastWriteTime) }); cmdInsert.ExecuteNonQuery(); copyCount++; } else { DateTime lastWriteTime = DateTime.Parse(obj.ToString()); if (!DateTime.Parse(NextFile.LastWriteTime.ToString()).Equals(lastWriteTime)) { String fullname = folder.FullName; string newpath = fullname.Replace(srcPath, destPath + "\\" + DateTime.Now.ToString("yyyyMMdd")); DirectoryInfo newFolder = new DirectoryInfo(newpath); if (!newFolder.Exists) { newFolder.Create(); } NextFile.CopyTo(newpath + "\\" + NextFile.Name, true); SQLiteCommand cmdUpdate = new SQLiteCommand(conn);//實例化SQL命令 cmdUpdate.CommandText = "update " + SQLHelper.TB_NAME + " set lastWriteTime=@lastWriteTime where fullPath=@fullPath"; cmdUpdate.Parameters.AddRange(new[] {//添加參數 new SQLiteParameter("@fullPath", NextFile.FullName), new SQLiteParameter("@lastWriteTime", NextFile.LastWriteTime) }); cmdUpdate.ExecuteNonQuery(); copyCount++; } } Console.WriteLine("已遍歷第" + (++fileCount) + "個文件"); } } }