Click here to Skip to main content
Click here to Skip to main content

Tagged as

Go to top

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

, 4 Jul 2013
Rate this:
Please Sign up or sign in to vote.
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.

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!

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).

// 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:

// 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:

// 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.

// 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:

// 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)

Share

About the Author

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

Comments and Discussions

 
SuggestionSimple copying in one line PinmemberIbrahim Sediq3-Jan-14 17:46 
GeneralRe: Simple copying in one line PinprofessionalCanny Brisk4-Jan-14 20:39 
GeneralRe: Simple copying in one line PinmemberIbrahim Sediq21-Apr-14 18:53 
GeneralRe: Simple copying in one line PinprofessionalCanny Brisk21-Apr-14 19:44 
QuestionIs there another option to do this apart from recursion? PinmemberJoseph140829-Aug-13 3:58 
AnswerRe: Is there another option to do this apart from recursion? PinprofessionalCanny Brisk29-Aug-13 3:59 
QuestionRe: Is there another option to do this apart from recursion? PinmemberJoseph140829-Aug-13 4:01 
AnswerRe: Is there another option to do this apart from recursion? PinprofessionalCanny Brisk29-Aug-13 4:02 
QuestionRe: Is there another option to do this apart from recursion? PinmemberJoseph140829-Aug-13 4:03 
AnswerRe: Is there another option to do this apart from recursion? PinprofessionalCanny Brisk29-Aug-13 4:04 
GeneralRe: Is there another option to do this apart from recursion? PinmemberJoseph140829-Aug-13 4:33 
QuestionRe: Is there another option to do this apart from recursion? PinprofessionalCanny Brisk29-Aug-13 4:35 
AnswerRe: Is there another option to do this apart from recursion? PinmemberJoseph140829-Aug-13 4:36 
AnswerRe: Is there another option to do this apart from recursion? PinprofessionalCanny Brisk29-Aug-13 4:27 
GeneralRe: Is there another option to do this apart from recursion? PinmemberJoseph140829-Aug-13 4:33 
GeneralMy vote of 3 Pinmemberjohannesnestler29-Aug-13 1:01 
SuggestionUse EnumerateX rather than GetX PinmemberStephen Inglish4-Jul-13 2:42 
GeneralRe: Use EnumerateX rather than GetX PinprofessionalMaimonides4-Jul-13 3:04 
GeneralMy vote of 2 PinmemberAshutosh Phoujdar4-Jul-13 1:50 
QuestionXcopx Pinmemberrainermartin3-Feb-13 20:27 
AnswerRe: Xcopx PinmemberEdo Tzumer5-Feb-13 1:09 
GeneralMy vote of 5 PinmvpMichael Haephrati מיכאל האפרתי23-Jan-13 5:49 
GeneralMy vote of 1 Pinmemberjohannesnestler8-Jan-13 22:31 
GeneralRe: My vote of 1 PinmemberEdo Tzumer8-Jan-13 22:56 
GeneralRe: My vote of 1 Pinmemberhardsoft8-Jan-13 23:17 
Great function but lacks the ability to copy NTFS security and permissions but will save others developing the code.
 
Now if it had this improvement you would get my vote of a 5.
 
Hope this helps you to improve the code.
GeneralRe: My vote of 1 [modified] PinmemberEdo Tzumer8-Jan-13 23:32 
GeneralRe: My vote of 1 Pinmemberjohannesnestler8-Jan-13 23:25 
GeneralRe: My vote of 1 PinmemberEdo Tzumer8-Jan-13 23:35 
SuggestionRe: My vote of 1 Pinmemberbitterskittles9-Jan-13 1:44 
GeneralRe: My vote of 1 PinmemberEdo Tzumer9-Jan-13 2:15 
GeneralRe: My vote of 1 [modified] Pinmemberbitterskittles9-Jan-13 2:31 
GeneralRe: My vote of 1 PinmemberEdo Tzumer9-Jan-13 2:55 
GeneralRe: My vote of 1 PinmemberJoseph140827-Aug-13 23:55 
GeneralRe: My vote of 1 Pinmemberjohannesnestler29-Aug-13 1:01 
GeneralRe: My vote of 1 PinmemberJoseph140829-Aug-13 3:56 
GeneralMy vote of 1 PinmemberD.Net Solutions8-Jan-13 21:38 
GeneralRe: My vote of 1 [modified] PinmemberEdo Tzumer9-Jan-13 2:20 
QuestionNo article PinmemberD.Net Solutions8-Jan-13 21:38 
AnswerRe: No article PinmemberJoseph140828-Aug-13 0:00 

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

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

| Advertise | Privacy | Mobile
Web02 | 2.8.140905.1 | Last Updated 4 Jul 2013
Article Copyright 2013 by _Canny_Brisk_
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid