文件同步的完整代码
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO; using System.Diagnostics; using System.Threading; namespace FileSynchronization { public partial class Form1 : Form { #region 定义变量 /// <summary> /// 目标文件夹路径 /// </summary> string strSourceFileName = null; /// <summary> /// 目标文件夹路径 /// </summary> string strDestFileName = null; #endregion #region 构造函数 public Form1() { InitializeComponent(); Control.CheckForIllegalCrossThreadCalls = false;//不检查跨线程的调用是否合法 } #endregion #region 基本事件 /// <summary> /// 窗体加载事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Form1_Load(object sender, EventArgs e) { //strSourceFileName = this.txtSourceFile.Text.ToString(); //strDestFileName = this.txtTargetFile.Text.ToString(); //Thread thread = new Thread(ThreadFuntion); //thread.IsBackground = true;//获取或设置一个值,该值指示某个线程是否为后台线程。 //thread.Start();//导致操作系统将当前实例的状态更改为 ThreadState.Running。 } /// <summary> /// 按钮点击事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnStart_Click(object sender, EventArgs e) { strSourceFileName = this.txtSourceFile.Text.ToString(); strDestFileName = this.txtTargetFile.Text.ToString(); Thread thread = new Thread(ThreadFuntion); thread.IsBackground = true;//获取或设置一个值,该值指示某个线程是否为后台线程。 thread.Start();//导致操作系统将当前实例的状态更改为 ThreadState.Running。 } /// <summary> /// 线程执行的方法 /// </summary> private void ThreadFuntion() { try { int i = 0; while (true) { i++; DateTime dt = DateTime.Now; /////执行文件同步方法 FileSyn(strSourceFileName, strDestFileName); this.label3.Text = "第" + i + "次用时: " + (DateTime.Now - dt).ToString(); //Thread.Sleep(10000); } } catch { } } #endregion #region 执行文件同步方法 /// <summary> /// 执行文件同步方法 /// </summary> /// <param name="strSourceFileName">目标文件夹路径</param> /// <param name="strDestFileName">目标文件夹路径</param> private void FileSyn(string strSourceFileName, string strDestFileName) { try { //删除“目标文件夹”中多于“目标文件夹”中的文件及子文件夹 Delete(strSourceFileName, strDestFileName); //循环遍历目标文件夹下的文件夹及子文件夹,复制到目标文件夹中(包含重命名) Copy(strSourceFileName, strDestFileName); } catch { //MessageBox.Show("aa"); } } #endregion #region 删除目标文件夹中多于目标文件夹中的文件及文件夹 /// <summary> /// 文件或文件夹在目标文件夹中存在而目标文件夹中不存在,则将目标文件夹中的这些文件删除 /// </summary> /// <param name="fileSou">目标文件夹路径</param> /// <param name="dirDest">目标文件夹路径</param> private void Delete(string strSourceFileName, string strDestFileName) { List<string> FileSource = Directory.GetFiles(strSourceFileName).Select(s => System.IO.Path.GetFileName(s)).ToList(); List<string> FileDest = Directory.GetFiles(strDestFileName).Select(s => System.IO.Path.GetFileName(s)).ToList(); List<string> FolderSource = Directory.GetDirectories(strSourceFileName).Select(s => System.IO.Path.GetFileNameWithoutExtension(s)).ToList(); List<string> FolderDest = Directory.GetDirectories(strDestFileName).Select(s => System.IO.Path.GetFileNameWithoutExtension(s)).ToList(); foreach (string file in FileDest) { if (FileSource.IndexOf(file) < 0) { File.Delete(strDestFileName + "\\" + file); } } foreach (string folder in FolderDest) { if(FolderSource.IndexOf(folder)<0) { Directory.Delete(strDestFileName + "\\" + folder, true); } else { string strSourceName = Path.Combine(strSourceFileName, folder); string strdestName = Path.Combine(strDestFileName, folder); Delete(strSourceName, strdestName); } } #region 删除(不使用) ////lambda表达式获取文件、文件夹名称 //string[] SourceFileName = Directory.GetFiles(strSourceFileName).Select(s => System.IO.Path.GetFileName(s)).OrderBy(s => System.IO.Path.GetFileName(s)).ToArray(); //string[] SourceFolderName = Directory.GetDirectories(strSourceFileName).Select(a => System.IO.Path.GetFileNameWithoutExtension(a)).OrderBy(s => System.IO.Path.GetFileName(s)).ToArray(); //string[] DestFileName = Directory.GetFiles(strDestFileName).Select(s => System.IO.Path.GetFileName(s)).OrderBy(s => System.IO.Path.GetFileName(s)).ToArray(); //string[] DestFolderName = Directory.GetDirectories(strDestFileName).Select(a => System.IO.Path.GetFileNameWithoutExtension(a)).OrderBy(s => System.IO.Path.GetFileName(s)).ToArray(); #region 循环遍历目标文件夹,某文件在目标文件夹中存在而源文件夹中不存在,则删除该文件(只是文件) //////循环遍历目标文件夹,某文件在目标文件夹中存在而源文件夹中不存在,则删除该文件(只是文件) //foreach (string file in DestFileName) //{ // //检索与当前文件名称长度相等的文件 // string[] arrFileSou = SourceFileName.Where(d => d.Length == file.Length).ToArray(); // //二分法判断目标文件夹中当前文件是否在源文件夹也存在,如果不存在则删除目标文件夹中的当前文件 // if (!Binary(arrFileSou, file, arrFileSou.Length)) // { // File.Delete(strDestFileName + "\\" + file); // } //} #endregion #region 删除目标文件夹中对于源文件夹的文件夹 ////循环遍历目标文件夹,某文件夹在目标文件夹中存在而源文件夹中不存在,则删除该文件夹(针对子文件夹) // foreach (string dir in DestFolderName) // { // //检索与当前文件夹名称长度相等的文件夹 // string[] arrDirSource = SourceFolderName.Where(d => d.Length == dir.Length).ToArray(); // //二分法判断目标文件夹中当前文件夹在源文件夹中是否存在,若不存在则删除该文件夹,若存在则递归调用当前函数 // if (!Binary(arrDirSource, dir, arrDirSource.Length)) // { // Directory.Delete(strDestFileName + "\\" + dir, true); // } // else // { // string strSourceName = Path.Combine(strSourceFileName, dir); // string strdestName = Path.Combine(strDestFileName, dir); // Delete(strSourceName, strdestName); // } // } #endregion #endregion } #endregion #region 循环遍历源文件夹文件夹下的文件夹及子文件夹,复制到目标文件夹中 /// <summary> /// 循环遍历源文件夹文件夹下的文件夹及子文件夹,复制到目标文件夹中 /// </summary> /// <param name="strSourceFileName">目标文件夹路径</param> /// <param name="strDestFileName">目标文件夹路径</param> private void Copy(string strSourceFileName, string strDestFileName) { string[] SourceFileName = Directory.GetFiles(strSourceFileName).Select(s => System.IO.Path.GetFileName(s)).OrderBy(s => System.IO.Path.GetFileName(s)).ToArray(); string[] SourceFolderName = Directory.GetDirectories(strSourceFileName).Select(a => System.IO.Path.GetFileNameWithoutExtension(a)).OrderBy(s => System.IO.Path.GetFileName(s)).ToArray(); string[] DestFileName = Directory.GetFiles(strDestFileName).Select(s => System.IO.Path.GetFileName(s)).OrderBy(s => System.IO.Path.GetFileName(s)).ToArray(); string[] DestFolderName = Directory.GetDirectories(strDestFileName).Select(a => System.IO.Path.GetFileNameWithoutExtension(a)).OrderBy(s => System.IO.Path.GetFileName(s)).ToArray(); //循环遍历源文件夹(只是文件) foreach (string file in SourceFileName)//遍历源文件 { string[] arrFileDes = DestFileName.Where(s => s.Length == file.Length).ToArray(); //某文件在源文件夹中存在,目标文件夹中也存在时,比对两文件的上次修改时间,若不同这个替换 if (Binary(arrFileDes, file, arrFileDes.Length)) { //判断文件是否有过重命名或者修改 FileInfo fileA = new FileInfo(strSourceFileName + "\\" + file); FileInfo fileB = new FileInfo(strDestFileName + "\\" + file); if (fileA.LastWriteTime.ToString() != fileB.LastWriteTime.ToString()) { File.Delete(strDestFileName + "\\" + file);//删除目标文件,再复制 File.Copy(strSourceFileName + "\\" + file, strDestFileName + "\\" + file); } } else//某文件在源文件夹中存在而目标文件夹中不存在时,复制当前文件至目标文件夹 { File.Copy(strSourceFileName + "\\" + file, strDestFileName + "\\" + file); } } //遍历源文件夹的子文件夹 foreach (string dir in SourceFolderName) { string[] arrDirDest = DestFolderName.Where(s => s.Length == dir.Length).ToArray(); //如果不存在该文件夹,则先创建再向其中复制文件,存在则递归调用该函数 if (!Binary(arrDirDest, dir, arrDirDest.Length)) { string souName = Path.Combine(strSourceFileName, dir); string destName = Path.Combine(strDestFileName, dir); Directory.CreateDirectory(destName);//创建该文件夹 Copy(souName, destName);//递归调用 } else { string souName = Path.Combine(strSourceFileName, dir); string destName = Path.Combine(strDestFileName, dir); Copy(souName, destName);//递归调用 } } } #endregion #region 比对 #region 二分法 /// <summary> /// 二分法 /// </summary> /// <param name="array">查找的数组</param> /// <param name="key">被查找个关键字</param> /// <param name="n">数组长度</param> /// <returns></returns> private bool Binary(string[] array, string key, int n) { if (n <= 0) { return false; } else { int left = 0;//数组左端索引 int right = n - 1;//数组有段索引 int mid = (left + right) / 2; while (left < right && array[mid] != key) { if (string.Compare(key, array[mid]) < 0) { right = mid - 1; } else if (string.Compare(key, array[mid]) > 0) { left = mid + 1; } mid = (left + right) / 2; } if (string.Compare(array[mid], key) == 0) { return true; } return false; } } #endregion #region 三分法(有问题) /// <summary> /// 三分法 /// </summary> /// <param name="array">查找的数组</param> /// <param name="key">被查找个关键字</param> /// <param name="n">数组长度</param> /// <returns></returns> private bool SanFen(string[] array, string key, int n) { if (n <= 0) { return false; } else { int left = 0;//数组左端索引 int right = n - 1;//数组有段索引 int midleft = (left + right) / 3; int midright = 2 * midleft; bool isCunzai = false; while (left < right && midleft < midright && string.Compare(key, array[left]) != 0 || string.Compare(key, array[midleft]) != 0 || string.Compare(key, array[midright]) != 0 || string.Compare(key, array[right]) != 0) { //if (string.Compare(key, array[left]) == 0 || string.Compare(key, array[midleft]) == 0 || string.Compare(key, array[midright]) == 0 || string.Compare(key, array[right]) == 0) //{ // isCunzai = true; // break; //} if (string.Compare(key, array[midleft]) < 0) { left = 0; right = midleft - 1; } else if (string.Compare(key, array[midleft]) > 0 && string.Compare(key, array[midright]) < 0) { left = midleft + 1; right = midright - 1; } else if (string.Compare(key, array[midright]) > 0) { left = midright + 1; } midleft = (left + right) / 3; midright = 2 * midleft; } if (isCunzai == true || string.Compare(array[left], key) == 0 || string.Compare(array[right], key) == 0 || string.Compare(array[(left + right) / 2], key) == 0 || string.Compare(array[(left + right) / 3], key) == 0) { return true; } return false; } } #endregion #endregion } }
时间: 2024-11-05 02:36:05