65.9K
CodeProject is changing. Read more.
Home

Recursively Copy folder contents to another in C#

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0 vote)

Nov 8, 2011

CPOL
viewsIcon

7694

I have made some improvements without making a change to the methodology.Note: Yes, the performance difference between string.format and concat is negligable when you are working with File-IO. Still we are here to educate.public static class FolderManager{ public static Exception...

I have made some improvements without making a change to the methodology. Note: Yes, the performance difference between string.format and concat is negligable when you are working with File-IO. Still we are here to educate.
public static class FolderManager
{
  public static Exception LastError { get; private set; }
  public static void ClearLastError()
  {
    LastError = null;
  }

  //Microsoft naming conventions, parameters should start with lower case.
  //That way you can differentiate betweeen parameters and properties.
  public static bool CopyFolderContents(string sourcePath, string destinationPath)
  {
    //Do not reuse variables, introduce new ones so that during debugging you can check start and end value.
    string slashEndingSourcePath = sourcePath.EndsWith(@"\") ? sourcePath : sourcePath + @"\";
    string slashEndingDestinationPath = destinationPath.EndsWith(@"\") ? destinationPath : destinationPath + @"\";

    try
    {
      if (Directory.Exists(slashEndingSourcePath))
      {
        if (!Directory.Exists(slashEndingDestinationPath))
        {
          Directory.CreateDirectory(slashEndingDestinationPath);
        }

        foreach (string files in Directory.GetFiles(slashEndingSourcePath))
        {
          FileInfo fileInfo = new FileInfo(files);
          // because it checks to see if the path ends with a "\", 
          //which we already did at the top. The overhead for string.Format, 
          // when you are not parsing numbers, is overkill!
          // String concat is much faster, see StringTest below as proof.
          // Also, because I did not reuse the destinationPath-variable and 
          // gave the new variable a good name,  I can now notice that the '\' in 
          //the original string.format is not needed, the path already ends in slash.
          fileInfo.CopyTo(slashEndingDestinationPath + fileInfo.Name, true);
          // fileInfo.CopyTo(string.Format(@"{0}\{1}", slashEndingDestinationPath, fileInfo.Name), true);
        }

        foreach (string drs in Directory.GetDirectories(slashEndingSourcePath))
        {
          DirectoryInfo directoryInfo = new DirectoryInfo(drs);
          if (!CopyFolderContents(drs, slashEndingDestinationPath + directoryInfo.Name))
          {
            return false;
          }
        }
      }
      return true;
    }
    // I really hate silently catching exceptions, lets log it instead.
    catch (Exception ex)
    {
      //This way, the user of the code can ask why it failed.
      LastError = ex;
      return false;
    }
  }

  public static void StringTest()
  {
    long start = DateTime.Now.Ticks;
    for (int i = 0; i < 10000000; i++)
    {
      string x = string.Format(@"{0}\{1}", "sdfsghhwerhresdgwe4tfg423tfgoiosdufgosdgwe4tfg423tfgoiosdufgo", "sdgwe4tfg423tfgoiosdufgo");
    }
    MessageBox.Show(new TimeSpan(DateTime.Now.Ticks - start).ToString());
    start = DateTime.Now.Ticks;
    for (int i = 0; i < 10000000; i++)
    {
      string x = "sdfsghhwerhresdgwe4tfg423tfgoiosdufgosdgwe4tfg423tfgoiosdufgo" + "\\" + "sdgwe4tfg423tfgoiosdufgo";
    }
    MessageBox.Show(new TimeSpan(DateTime.Now.Ticks - start).ToString());
  }
}