0

I want to copy the specific directory and all sub directories and files with C#.

With this code I have a problem. This code creates another folder in a sub folder with the same name, but I can't find where the mistake is.

Directory path  => D:\FolderAAA\FolderBBB\File1
Target (result): => E:\FolderAAA\FolderBBB\FolderBBB\File1 (issue with double bbb folder)

This is my code

private void CopyTheDirectory(string directoryPath, string targetPath)
{
    DirectoryInfo d_info = new DirectoryInfo(directoryPath);
    Directory.CreateDirectory(Path.Combine(targetPath, d_info.Name));

    var files = Directory.GetFiles(d_info.FullName);
    var directories = Directory.GetDirectories(directoryPath);

    foreach(var file in files)
    {
        File.Copy(file, Path.Combine(Path.Combine(targetPath, d_info.Name), Path.GetFileName(file)));
    }

    foreach(var directory in directories)
    {

        CopyTheDirectory(directory, Path.Combine(Path.Combine(targetPath, d_info.Name), Path.GetFileName(directory)));
    }
}
Zohar Peled
  • 79,642
  • 10
  • 69
  • 121
amir mehr
  • 75
  • 1
  • 9

2 Answers2

1

You are getting the sub directories wrong. You should be using d_info.GetDirectories, which will return an array of DirectoryInfo instead. This makes the building of the target paths for both files and sub directories much simpler and less error-prone.

Here's a fixed version of your code:

private void CopyTheDirectory(string directoryPath, string targetPath)
{
    DirectoryInfo d_info = new DirectoryInfo(directoryPath);
    Directory.CreateDirectory(targetPath);

    var files = Directory.GetFiles(d_info.FullName);
    var directories = d_info.GetDirectories();

    foreach (var file in files)
    {
        File.Copy(file, Path.Combine(targetPath, Path.GetFileName(file)));
    }

    foreach (var directory in directories)
    {
        CopyTheDirectory(directory.FullName, Path.Combine(targetPath, directory.Name));
    }
}

Update

Based on your comments to the answer, here's what I think you are looking for:

private void CopyTheDirectory(string directoryPath, string targetPath)
{
    DirectoryInfo d_info = new DirectoryInfo(directoryPath);

    var toPath = targetPath.EndsWith(Path.DirectorySeparatorChar.ToString() + d_info.Name) ? targetPath : Path.Combine(targetPath, d_info.Name);
    Directory.CreateDirectory(toPath);

    var files = Directory.GetFiles(d_info.FullName);
    var directories = d_info.GetDirectories();

    foreach (var file in files)
    {
        File.Copy(file, Path.Combine(toPath, Path.GetFileName(file)));
    }

    foreach (var directory in directories)
    {
        CopyTheDirectory(directory.FullName, Path.Combine(toPath, directory.Name));
    }
}
Zohar Peled
  • 79,642
  • 10
  • 69
  • 121
  • I used this code but it's not work well too . It copied all the files and folders in one directory for example E:\ – amir mehr Feb 24 '19 at 07:49
  • This answer is right, you've combined the directory name twice. Once is at the beginning and another is the second foreach loop, remove either of them. – WildWind Feb 24 '19 at 08:07
  • But i don't know what should i do ! if I change a code then all code get wrong !! – amir mehr Feb 24 '19 at 08:12
  • I've tested the code before posting, it copies the entire directory tree and files from the `directoryPath` to the `targetPath`. I'm not sure what you've done wrong. – Zohar Peled Feb 24 '19 at 08:32
  • @ZoharPeled It's for the Directory . When i copy the directory with the name "F1" and select target to E:\ it's copies directories and files into E:\ drive root . I want to copy in the E:\F1 ... I mean the app must create a directory at first – amir mehr Feb 24 '19 at 09:20
  • It copies the directory into the target path. do you want it to create the top-level source directory in the target path before starting to copying? – Zohar Peled Feb 24 '19 at 09:38
0

This must work !

public void CopyFolderNdContents(string sourceFolder, string destFolder)
    {
        try
        {
            if (!Directory.Exists(destFolder))
                Directory.CreateDirectory(destFolder);

            string[] files = Directory.GetFiles(sourceFolder);
            foreach (string file in files)
            {
                string name = Path.GetFileName(file);
                string dest = Path.Combine(destFolder, name);

                if (!File.Exists(file))  // If file exists don't copy !!
                    File.Copy(file, dest);
            }
            string[] folders = Directory.GetDirectories(sourceFolder);
            foreach (string folder in folders)
            {
                string name = Path.GetFileName(folder);
                string dest = Path.Combine(destFolder, name);
                CopyFolderNdContents(folder, dest);
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }
    }

private void btnCopyFoder_Click(object sender, EventArgs e)
    {
        CopyFolderNdContents(@"C:\FolderAAA", @"D:\FolderAAA");
    }
Amit K.S
  • 299
  • 3
  • 9