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

    }
}
时间: 2024-11-05 02:36:05

C#中保持文件夹A与B同步的相关文章

CAML获取SharePoint文档库中除文件夹外所有文档

方法一: ? 1 2 3 4 <QueryOptions>         <ViewAttributes Scope="Recursive" />     </QueryOptions> </query> 方法二: ? 1 2 3 4 5 <View Scope="RecursiveAll">     <Query>         <Where>...</Where>

每日学习心得:SharePoint 为列表中的文件夹添加子项(文件夹)、新增指定内容类型的子项、查询列表中指定的文件夹下的内容

前言: 这里主要是针对列表中的文件下新增子项的操作,同时在新建子项时,可以为子项指定特定的内容类型,在某些时候需要查询指定的文件夹下的内容,针对这些场景都一一给力示例和说明,都是一些很小的知识点,希望能够对大家有所帮助. 1.   在列表中为列表项添加子项 为列表添加子项大家都很熟悉,但是如何为列表项添加子项呢?例如列表项是一个文件夹,如何为该文件夹添加子项呢?这里就用到了List.AddItem()方法,具体示例如下: 首先我们要获取列表中的子项: SPListItem root_item=l

沙盒模型中各文件夹及操作

某个iphone工程进行文件操作有此工程对应的指定的位置,不能逾越. iphone沙箱模型的有四个文件夹,分别是什么,永久数据存储一般放在什么位置,得到模拟器的路径的简单方式是什么. documents,tmp,app,Library. (NSHomeDirectory()), 手动保存的文件在documents文件里 Nsuserdefaults保存的文件在tmp文件夹里 Documents 目录:您应该将所有de应用程序数据文件写入到这个目录下.这个目录用于存储用户数据或其它应该定期备份的信

mint/ubuntu 在终端 / Shell中 打开文件夹

我知道的有两种方法, 都是命令后面加路径(nautilus|pcmanfm dir_path) 方法一: 使用 nautilus 安装:sudo apt-get intstall nautilus 效果:nautilus ~ 方法二: 使用 pcmanfm 安装:sudo apt-get intstall pcmanfm 效果:pcmanfm ~ 不过这两种方法都让我有点不爽,因为和原生系统的不一样,还有一点慢, 现在还可以忍,如果你有更好的方法请留言.(原生系统如下) mint/ubuntu

Win10正式版删除此电脑中的文件夹

Win10正式版如何删除"此电脑"中冗余的6个文件夹 将以下代码保存为123.bat文件,用管理员权限运行,选择显示或隐藏 _____________________________________________________________ @echo off set /P aa="隐藏此电脑中的文件夹请按1,按其它任意键则显示." if /i %aa%==1 ( set sss=Hide ) else ( set sss=show ) echo y | re

cceditbox和cocostudio联合界面点击事件无响应问题,Android中创建文件夹问题

这两个问题折腾了我一天多时间,尽快下班时候把创建文件夹问题给解决了,刚把cceditbox点击事件无响应问题解决了.真是大爽. 1.创建文件夹 _mkdir()这个c函数就行,在vs ide中,定位的头文件是direct.h,但是这个文件不被ndk编译通过,没有这个文件.好吧,死脑筋,开始怀疑eclipse库路径设置有问题,但是不知道哪不对,搜索到了头大地步,好吧,认真仔细一看,原来是在ndk中,_mkdir函数放在了#include <sys/stat.h>中,改为这个头文件就行了. 2.点

Mac系统中各个文件夹简单介绍(转)

一.说明: Mac OS X,这是一个基于UNIX核心的系统,增强了系统的稳定性.性能以及响应能力.它能通过对称多处理技术充分发挥双处理器的优势,提供无与伦比的2D.3D和多媒体图形性能以及广泛的字体支持和集成的PDA功能.MAC OSX通过Classic环境几乎可以支持所有的MacOS9应用程序,直观的Aqua用户界面使Mac intosh的易用性又达到了一个全新的水平. 二.MAC硬盘中各个文件夹 打开Macintosh HD你会发现内中有四个文件夹,分别有——应用程序(Applicatio

使用VS2010开发Qt程序的4点经验(QT4到QT5的升级,更改sln文件,切换工程使用的Qt库,在VS的Solution Explorer视图中建立文件夹)

导读 相比于Qt Creator,我更喜欢用VS2010来进行开发.虽然启动时间相对较慢,但是VS下强大的快捷键和丰富的插件,以及使用多年的经验,都让我觉得在开发过程中得心应手.其中最重要的一点是,有时候Qt Creator报的错误莫名其妙.要根据提示找到错误根源显得无从下手.而VS的一般错误说明都比较人性化,即便在某些时候无从解决,也可以通过搜索引擎大致定位出错误的源头.下面是在调试网上的一些源代码的时候,积累下来的一点经验,记下来一来备忘,二来也可供后来人参考. The system can

[]如何在Windows 10中更改文件夹背景颜色

ini文件.我们甚至可以使用相同的技术将图片设置为文件夹背景. 已有工具可以更改Windows 7中Windows资源管理器背景的颜色,并将图像设置为Windows 7中的文件夹背景,但这些工具与Windows 8引入的新文件管理器不兼容. 由于某些原因,这些文件夹背景更改工具在Windows 10和Windows 8/8中不起作用.1.自从Windows 10发布以来,用户一直在要求我们提出一种将图片设置为文件夹背景或至少更改文件夹背景颜色的方法,我们决定提出本指南. 如果您在Windows