Search code examples
c#filedirectorycopy-paste

How to copy and paste a whole directory to a new path recursively?


I want to move a directory as a copy/paste routine, by keeping its structure as it is. I am not looking only for the files within all subfolders in a directory then copy/paste them (as this solution), instead I want to clone the whole thing and keep its structure as it is (Tree -> subfolders and files), exactly like a copy and paste routine.

So I found this function that copies a folder full of files to a new path:

Folder -> File(s)

The function behaves as known as the copy/paste routine. It takes SourcePath, DestinationPath and boolean value to OverWriteExisting. Nice and small but too bad it wasn't marked as the actual answer of that question there (recommend a rate).

But what if I want to move a whole directory? In other words, what if I have a folder that has folders of folders of folders of files and etc? And maybe it is unknown the file structure tree size like this:

Folder -> Folder(s) -> ... -> Folder(s) -> File(s)

I am using the below routine to copy/paste a folder that has folders. But here I know that I only have one level of folders so only one foreach loop is required:

foreach (var Folder in DestinationFolder) // here I know that I have only one level of folders to reach the files
{
    CopyDirectory(FolderPath, DestinationPath, false); // use that function to copy the files
}

This above function serves this directory structure:

Folder -> Folder(s) -> File(s)

I tried this and it didn't do what I want. I only retrieve all files while it searches all the subfolders. Which is not what I want. I want to keep the subfolders and the original structure as it is. Here I get four files instead of the directory structed as it is, subfolders and their subfolders, subfolders, files. Only four because it removes duplicates which I do not want this to happen because I need all of them.

Here is my current structure(but my question is global to any directory):

Folder -> Folders -> Folders + Files

Here is what the below code does in the new path:

NewFolder -> AllFilesFoundInAnySubfolder

dialog.FileName = dialog.FileName.Replace(".xml", ""); // get the destination path
DirectoryInfo dirInfo = new DirectoryInfo(dialog.FileName);

if (dirInfo.Exists == false)
    Directory.CreateDirectory(dialog.FileName);

List<String> EverythingInTheDirectory = Directory
                    .GetFiles(FileStructure.baseSessionPath + "\\" + SelectedSession.Name, "*.*", SearchOption.AllDirectories).ToList(); // source

foreach (string file in EverythingInTheDirectory)
{
    FileInfo mFile = new FileInfo(file);
    // to remove name collusion
    if (new FileInfo(dirInfo + "\\" + mFile.Name).Exists == false)
        mFile.MoveTo(dirInfo + "\\" + mFile.Name);
}

How to move the whole directory with unknown size and keep its structure as it is? Not get only the files from a directory and move them!


Solution

  • Here is an example that will recursively clone a directory to another destination directory.

    class Program
    {
        static void Main(string[] args)
        {
            CloneDirectory(@"C:\SomeRoot", @"C:\SomeOtherRoot");
        }
    
        private static void CloneDirectory(string root, string dest)
        {
            foreach (var directory in Directory.GetDirectories(root))
            {
                //Get the path of the new directory
                var newDirectory = Path.Combine(dest, Path.GetFileName(directory));
                //Create the directory if it doesn't already exist
                Directory.CreateDirectory(newDirectory);
                //Recursively clone the directory
                CloneDirectory(directory, newDirectory);
            }
    
            foreach (var file in Directory.GetFiles(root))
            {
                File.Copy(file, Path.Combine(dest, Path.GetFileName(file)));
            }
        }
    }