Click here to Skip to main content
15,867,453 members
Articles / Programming Languages / C#
Tip/Trick

Folder [Directory] Deep Copy (including sub directories) in .NET

Rate me:
Please Sign up or sign in to vote.
4.00/5 (10 votes)
4 Jul 2013CPOL3 min read 214.1K   34   40
Copy a folder [i.e. directory] including subfolders and files (recursively)

Introduction

Ever needed to copy folder A to location B including sub-directories & files? Sounds fairly simple but, here's the thing - there's no deep copy of a folder in .NET ... (it's actually not entirely true, as I will illustrate below).

Background

I'd like to show some example methods of doing so, just to save you those "couple of minutes" of implementation, and to provide best practice, fault avoidance and various approaches of implementation.

Using the Code

First, the most "clean" and simple approach:

Note: This approach is using recursion, so for a massive folder tree, you might encounter a StackOverflow exception thrown.

C#
public static void DeepCopy(DirectoryInfo source, DirectoryInfo target)
{

    // Recursively call the DeepCopy Method for each Directory
    foreach (DirectoryInfo dir in source.GetDirectories())
        DeepCopy(dir, target.CreateSubdirectory(dir.Name));

    // Go ahead and copy each file in "source" to the "target" directory
    foreach (FileInfo file in source.GetFiles())
        file.CopyTo(Path.Combine(target.FullName, file.Name));

}  

Now this code is the basic to "copy & paste" to your Util class.

Important: There may be an ancestry logical flaw you should check and alert the method caller: You should avoid trying to copy C:\root to C:\root\child since the root folder will endlessly grow as a result of the copy itself!

C#
if (target.FullName.Contains(source.FullName))
    throw new exception("Cannot perform DeepCopy: Ancestry conflict detected");  

I've mentioned in the introduction section that there's actually a way to do this in .NET.

You can use the function FileSystem.CopyDirectory: (VB only).

* I'm not sure if they check for the ancestry conflict (but it's just one line of code to test it and I leave to you as homework).

C#
// Note that this is a function from the namespace Microsoft.VisualBasic.FileIO
// Assembly: Microsoft.VisualBasic (in Microsoft.VisualBasic.dll)
public static void CopyDirectory(
    string sourceDirectoryName,
    string destinationDirectoryName
) 

and you can use it like this, for example:

C#
// in VB.NET
My.Computer.FileSystem.CopyDirectory(source , target ,True)

The above use will replace source and target with the path and name of the directory you wish to copy and the location to which you wish to copy it.

Some Others Things You May Wish to Perform

Now, not always do you wish to copy the whole folders with every file in it.

You may wish to, for example copy the whole folder, but to exclude folders or files that answer to some criteria, in which case you add a RegularExpression filter.

The most simple extension to the first implementation would be:

C#
// This method uses Regular Expressions
// So you'll need to add 'using System.Text.RegularExpressions;'
public static void DeepCopy(DirectoryInfo source, DirectoryInfo target, string excludePattern)
{
    // Go through the Directories and recursively call the DeepCopy Method for each one
    foreach (DirectoryInfo dir in source.GetDirectories())
    {
        Match match = Regex.Match(dir.Name, excludePattern);
 
        if (!match.Success)
            DeepCopy(dir, target.CreateSubdirectory(dir.Name), excludePattern);
    }
 
    // Go ahead and copy each file to the target directory
    foreach (FileInfo file in source.GetFiles())
    {
        Match match = Regex.Match(file.Name, excludePattern);
 
        if (!match.Success)
            file.CopyTo(Path.Combine(target.FullName, file.Name)); 
    }
}

Copy the Directory Security As Well As the Content

As a tip request I received in a great comment, let's add another feature:

Copy the NTFS Access Control of folder Source to folder Target, let's give it a shot.

C#
// You'll need to add using 'System.Security.AccessControl' for this code
public static void DeepCopy(DirectoryInfo source, DirectoryInfo target)
{
    foreach (DirectoryInfo dir in source.GetDirectories())
    {
        DirectoryInfo SubDir = target.CreateSubdirectory(dir.Name)
    

        // --- IMPROVED SECTION ---
        // Set the security settings for the new directory same as the source dir
        SubDir.SetAccessControl( 
            new DirectorySecurity(dir.FullPath, AccessControlSections.All));
    

        DeepCopy(dir, SubDir);
    }
     
    foreach (FileInfo file in source.GetFiles())
        file.CopyTo(Path.Combine(target.FullName, file.Name));
 
}   

Using XCOPY- An Altogether Different Approach

Of course, there's always the down to earth approach to achieve things that the world does not want to let me do the "right way".

And I mean to use a process that does the work for you with good'ol XCopy.

Check out this following sample:

C#
// add using System.Diagnostics;
Process process = new Process();
process.StartInfo.FileName = "xcopy";
process.StartInfo.Arguments = @"c:\source c:\destination /e /h /c /I";
process.Start();  

When you copy or move files and folders by using Windows Explorer, the permissions that are set on the files or folders may change. For example, when you copy a file in an NTFS file system volume or between two NTFS volumes, Windows 2000 treats it as a new file. As a new file, it takes on the permissions of the destination folder, and you become the CREATOR OWNER.

Note: You must have Write permission for the destination folder to copy files and folders. You can use the XCopy command with the /O/X/E/H/K switches to copy the files and retain the existing permissions that have been specifically applied to the file or files.

These switches have the following effects:

  • /E - Copies folders and subfolders, including empty ones
  • /H - Copies hidden and system files also
  • /K - Copies attributes. Typically, Xcopy resets read-only attributes
  • /O - Copies file ownership and ACL information

/X - Copies file audit settings (implies /O).

I think you get the picture, if you are older than XXX [varies with time] years and have actually worked outside the Visual Studio environment [yes, some developers actually have never].

Sum Up

I'd appreciate any suggestions and/or other thoughts you may have to this issue.

Cheers, Edo

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Chief Technology Officer
United States United States
Senior dish washing consultant for over 25 years!

Comments and Discussions

 
QuestionDeep copy Pin
Member 1296921922-Mar-19 9:01
Member 1296921922-Mar-19 9:01 
SuggestionSimple copying in one line Pin
Ibrahim Sediq3-Jan-14 17:46
Ibrahim Sediq3-Jan-14 17:46 
GeneralRe: Simple copying in one line Pin
Joezer BH4-Jan-14 20:39
professionalJoezer BH4-Jan-14 20:39 
GeneralRe: Simple copying in one line Pin
Ibrahim Sediq21-Apr-14 18:53
Ibrahim Sediq21-Apr-14 18:53 
GeneralRe: Simple copying in one line Pin
Joezer BH21-Apr-14 19:44
professionalJoezer BH21-Apr-14 19:44 
QuestionIs there another option to do this apart from recursion? Pin
Jo Mua`mar29-Aug-13 3:58
Jo Mua`mar29-Aug-13 3:58 
AnswerRe: Is there another option to do this apart from recursion? Pin
Joezer BH29-Aug-13 3:59
professionalJoezer BH29-Aug-13 3:59 
QuestionRe: Is there another option to do this apart from recursion? Pin
Jo Mua`mar29-Aug-13 4:01
Jo Mua`mar29-Aug-13 4:01 
AnswerRe: Is there another option to do this apart from recursion? Pin
Joezer BH29-Aug-13 4:02
professionalJoezer BH29-Aug-13 4:02 
QuestionRe: Is there another option to do this apart from recursion? Pin
Jo Mua`mar29-Aug-13 4:03
Jo Mua`mar29-Aug-13 4:03 
AnswerRe: Is there another option to do this apart from recursion? Pin
Joezer BH29-Aug-13 4:04
professionalJoezer BH29-Aug-13 4:04 
GeneralRe: Is there another option to do this apart from recursion? Pin
Jo Mua`mar29-Aug-13 4:33
Jo Mua`mar29-Aug-13 4:33 
QuestionRe: Is there another option to do this apart from recursion? Pin
Joezer BH29-Aug-13 4:35
professionalJoezer BH29-Aug-13 4:35 
AnswerRe: Is there another option to do this apart from recursion? Pin
Jo Mua`mar29-Aug-13 4:36
Jo Mua`mar29-Aug-13 4:36 
AnswerRe: Is there another option to do this apart from recursion? Pin
Joezer BH29-Aug-13 4:27
professionalJoezer BH29-Aug-13 4:27 
GeneralRe: Is there another option to do this apart from recursion? Pin
Jo Mua`mar29-Aug-13 4:33
Jo Mua`mar29-Aug-13 4:33 
GeneralMy vote of 3 Pin
johannesnestler29-Aug-13 1:01
johannesnestler29-Aug-13 1:01 
SuggestionUse EnumerateX rather than GetX Pin
Stephen Inglish4-Jul-13 2:42
Stephen Inglish4-Jul-13 2:42 
GeneralRe: Use EnumerateX rather than GetX Pin
Joezer BH4-Jul-13 3:04
professionalJoezer BH4-Jul-13 3:04 
GeneralMy vote of 2 Pin
Ashutosh Phoujdar4-Jul-13 1:50
Ashutosh Phoujdar4-Jul-13 1:50 
QuestionXcopx Pin
rAINERmARTIN3-Feb-13 20:27
rAINERmARTIN3-Feb-13 20:27 
AnswerRe: Xcopx Pin
Joezer BH5-Feb-13 1:09
professionalJoezer BH5-Feb-13 1:09 
GeneralMy vote of 5 Pin
Michael Haephrati23-Jan-13 5:49
professionalMichael Haephrati23-Jan-13 5:49 
GeneralMy vote of 1 Pin
johannesnestler8-Jan-13 22:31
johannesnestler8-Jan-13 22:31 
GeneralRe: My vote of 1 Pin
Joezer BH8-Jan-13 22:56
professionalJoezer BH8-Jan-13 22:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.