C#中保持文件夹A与B同步

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
    }
}


知识共享许可协议
《C#中保持文件夹A与B同步》常伟华 创作。
采用 知识共享 署名-相同方式共享 3.0 中国大陆 许可协议进行许可。
  • 多说评论
  • 签名
  • 新浪微博
  • 默认评论
  • Tab Header 5

0 条评论 / 点击此处发表评论

Tab Content 5

开发技术


开发平台和工具

sitemap     164.36ms