在本地 c# 同步两个文件夹中的操作

Sync actions in two folders locally c#

我正在学习 C#,我有一个任务:
同步两个目录的内容。 给定两个目录的路径 - dir1 和 dir2,那么 dir2 应该与目录 1 同步:

我有一些关于如何做到这一点的逻辑,但我不知道如何实施it.I 用谷歌搜索整个互联网以找到一个起点,但没有成功。
我从这个开始:

using System.Security.Cryptography;

class Program
{
    static void Main(string[] args)
    {
        string sourcePath = @"C:\Users\artio\Desktop\FASassignment\root\dir1";
        string destinationPath = @"C:\Users\artio\Desktop\FASassignment\root\dir2";

        string[] dirsInSourcePath = Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories);
        string[] dirsInDestinationPath = Directory.GetDirectories(destinationPath, "*", SearchOption.AllDirectories);

        var filesInSourcePath = Directory.GetFiles(sourcePath, "*", SearchOption.AllDirectories);
        var filesInDestinationPath = Directory.GetFiles(destinationPath,"*",SearchOption.AllDirectories);



        //Directories in source Path
        foreach (string dir in dirsInSourcePath)
        {
            Console.WriteLine("sourcePath:{0}", dir);
            Directory.CreateDirectory(dir);
        }

        //Directories in destination path
        foreach (string dir in dirsInDestinationPath)
        {
            Console.WriteLine("destinationPath:{0} ", dir);
        }

        //Files in source path
        foreach (var file in filesInSourcePath)
        {
            Console.WriteLine(Path.GetFileName(file));
        }

        //Files in destination path
        foreach (var file in filesInDestinationPath)
        {
            Console.WriteLine(Path.GetFileName(file));
        }
    }

}  

据我了解,我应该检查dir1中是否有一些文件夹和文件,如果是,则将它们复制到文件夹2中,依此类推,但是如何做到这一点?我已经焦头烂额两天了,不知道..请帮忙。

编辑:对于第一点和第二点,我找到了解决方案。 :

public static void CopyFolderContents(string sourceFolder, string destinationFolder, string mask, Boolean createFolders, Boolean recurseFolders)
    {
        try
        {
            /*if (!sourceFolder.EndsWith(@"\")) { sourceFolder += @"\"; }
            if (!destinationFolder.EndsWith(@"\")) { destinationFolder += @"\"; }*/

            var exDir = sourceFolder;
            var dir = new DirectoryInfo(exDir);
            SearchOption so = (recurseFolders ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);

            foreach (string sourceFile in Directory.GetFiles(dir.ToString(), mask, so))
            {
                FileInfo srcFile = new FileInfo(sourceFile);
                string srcFileName = srcFile.Name;

                // Create a destination that matches the source structure
                FileInfo destFile = new FileInfo(destinationFolder + srcFile.FullName.Replace(sourceFolder, ""));

                if (!Directory.Exists(destFile.DirectoryName) && createFolders)
                {
                    Directory.CreateDirectory(destFile.DirectoryName);
                }

                if (srcFile.LastWriteTime > destFile.LastWriteTime || !destFile.Exists)
                {
                    File.Copy(srcFile.FullName, destFile.FullName, true);
                }
            }
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine(ex.Message + Environment.NewLine + Environment.NewLine + ex.StackTrace);
        }
    }  

不完美,但works.How这个功能应该改进:添加异步复制,并比较文件的哈希值,不要再次复制相同的文件。怎么做?

所以,经过一段时间的更多研究,我想出了这个解决方案:

using System.Diagnostics;

class Program
{
    static void Main(string[] args)
    {
        string sourcePath = @"C:\Users\artio\Desktop\FASassignment\root\dir1";
        string destinationPath = @"C:\Users\artio\Desktop\FASassignment\root\dir2";
        var source = new DirectoryInfo(sourcePath);
        var destination = new DirectoryInfo(destinationPath);

        CopyFolderContents(sourcePath, destinationPath, "", true, true);
        DeleteAll(source, destination);
    }

    public static void CopyFolderContents(string sourceFolder, string destinationFolder, string mask, Boolean createFolders, Boolean recurseFolders)
    {
        try
        {

            var exDir = sourceFolder;
            var dir = new DirectoryInfo(exDir);
            var destDir = new DirectoryInfo(destinationFolder);

            SearchOption so = (recurseFolders ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);

            foreach (string sourceFile in Directory.GetFiles(dir.ToString(), mask, so))
            {
                FileInfo srcFile = new FileInfo(sourceFile);
                string srcFileName = srcFile.Name;

                // Create a destination that matches the source structure
                FileInfo destFile = new FileInfo(destinationFolder + srcFile.FullName.Replace(sourceFolder, ""));

                if (!Directory.Exists(destFile.DirectoryName) && createFolders)
                {
                    Directory.CreateDirectory(destFile.DirectoryName);
                }

                //Check if src file was modified and modify the destination file
                if (srcFile.LastWriteTime > destFile.LastWriteTime || !destFile.Exists)
                {
                    File.Copy(srcFile.FullName, destFile.FullName, true);
                }
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message + Environment.NewLine + Environment.NewLine + ex.StackTrace);
        }
    }

    private static void DeleteAll(DirectoryInfo source, DirectoryInfo target)
    {
        if (!source.Exists)
        {
            target.Delete(true);
            return;
        }

        // Delete each existing file in target directory not existing in the source directory.
        foreach (FileInfo fi in target.GetFiles())
        {
            var sourceFile = Path.Combine(source.FullName, fi.Name);
            if (!File.Exists(sourceFile)) //Source file doesn't exist, delete target file
            {
                fi.Delete();
            }
        }

        // Delete non existing files in each subdirectory using recursion.
        foreach (DirectoryInfo diTargetSubDir in target.GetDirectories())
        {
            DirectoryInfo nextSourceSubDir = new DirectoryInfo(Path.Combine(source.FullName, diTargetSubDir.Name));
            DeleteAll(nextSourceSubDir, diTargetSubDir);
        }
    }
}  

它该做的都做了,唯一缺少的是异步复制和sha比较,但至少我有一个解决方案。