3
votes

I'm quite stuck on this problem for a while now. I need to copy (update) everything from Folder1\directory1 to Updated\directory1 overwriting same files but not deleting files that already exist on Updated\directory1 but does not exist on Folder1\directory1. To make my question clearer, this is my expected results:

C:\Folder1\directory1

subfolder1

subtext1.txt (2KB)

subfolder2

name.txt (2KB)

C:\Updated\directory1

subfolder1

subtext1.txt (1KB)

subtext2.txt (2KB)

Expected Result:

C:\Updated\directory1

subfolder1

subtext1.txt (2KB) <--- updated

subtext2.txt (2KB)

subfolder2 <--- added

name.txt (2KB) <--- added

I'm currently using Directory.Move(source, destination) but I'm having trouble about the destination part since some of it's destination folder is non-existent. My only idea is to use String.Trim to determine if there's additional folders but I can't really use it since the directories are supposed to be dynamic (there can be more subdirectories or more folders). I'm really stuck. Can you recommend some hints or some codes to get my stuff moving? Thanks!

4

4 Answers

3
votes

I got this example from msdn http://msdn.microsoft.com/en-us/library/cc148994.aspx I think this is what you looking for

// To copy all the files in one directory to another directory. 
    // Get the files in the source folder. (To recursively iterate through 
    // all subfolders under the current directory, see 
    // "How to: Iterate Through a Directory Tree.")
    // Note: Check for target path was performed previously 
    //       in this code example. 
    if (System.IO.Directory.Exists(sourcePath))
    {
        string[] files = System.IO.Directory.GetFiles(sourcePath);

        // Copy the files and overwrite destination files if they already exist. 
        foreach (string s in files)
        {
            // Use static Path methods to extract only the file name from the path.
            fileName = System.IO.Path.GetFileName(s);
            destFile = System.IO.Path.Combine(targetPath, fileName);
            System.IO.File.Copy(s, destFile, true);
        }
    }
    else
    {
        Console.WriteLine("Source path does not exist!");
    }

If you need to deal with non existing folder path you should create a new folder

if (System.IO.Directory.Exists(targetPath){
    System.IO.Directory.CreateDirectory(targetPath);
}
2
votes

Parallel fast copying of all files from a folder to a folder with any level of nesting

Tested on copying 100,000 files

using System.IO;
using System.Linq;

namespace Utilities
{
    public static class DirectoryUtilities
    {
        public static void Copy(string fromFolder, string toFolder, bool overwrite = false)
        {
            Directory
                .EnumerateFiles(fromFolder, "*.*", SearchOption.AllDirectories)
                .AsParallel()
                .ForAll(from =>
                {
                    var to = from.Replace(fromFolder, toFolder);

                    // Create directories if required
                    var toSubFolder = Path.GetDirectoryName(to);
                    if (!string.IsNullOrWhiteSpace(toSubFolder))
                    {
                        Directory.CreateDirectory(toSubFolder);
                    }

                    File.Copy(from, to, overwrite);
                });
        }
    }
}
1
votes
// This can be handled any way you want, I prefer constants
const string STABLE_FOLDER = @"C:\temp\stable\";
const string UPDATE_FOLDER = @"C:\temp\updated\";

// Get our files (recursive and any of them, based on the 2nd param of the Directory.GetFiles() method
string[] originalFiles = Directory.GetFiles(STABLE_FOLDER,"*", SearchOption.AllDirectories);

// Dealing with a string array, so let's use the actionable Array.ForEach() with a anonymous method
Array.ForEach(originalFiles, (originalFileLocation) => 
{       
    // Get the FileInfo for both of our files
    FileInfo originalFile = new FileInfo(originalFileLocation);
    FileInfo destFile = new FileInfo(originalFileLocation.Replace(STABLE_FOLDER, UPDATE_FOLDER)); 
                                    // ^^ We can fill the FileInfo() constructor with files that don't exist...

    // ... because we check it here
    if (destFile.Exists)
    {
        // Logic for files that exist applied here; if the original is larger, replace the updated files...
        if (originalFile.Length > destFile.Length)
        {
            originalFile.CopyTo(destFile.FullName, true);
        }
    }       
    else // ... otherwise create any missing directories and copy the folder over
    {
        Directory.CreateDirectory(destFile.DirectoryName); // Does nothing on directories that already exist
        originalFile.CopyTo(destFile.FullName,false); // Copy but don't over-write  
    }

});

This was a quick one-off... no error handling was implemented here.

1
votes

This will help you it is a generic recursive function so always merged subfolders as well.

    /// <summary>
    /// Directories the copy.
    /// </summary>
    /// <param name="sourceDirPath">The source dir path.</param>
    /// <param name="destDirName">Name of the destination dir.</param>
    /// <param name="isCopySubDirs">if set to <c>true</c> [is copy sub directories].</param>
    /// <returns></returns>
    public static void DirectoryCopy(string sourceDirPath, string destDirName, bool isCopySubDirs)
    {
        // Get the subdirectories for the specified directory.
        DirectoryInfo directoryInfo = new DirectoryInfo(sourceDirPath);
        DirectoryInfo[] directories = directoryInfo.GetDirectories();
        if (!directoryInfo.Exists)
        {
            throw new DirectoryNotFoundException("Source directory does not exist or could not be found: "
                + sourceDirPath);
        }
        DirectoryInfo parentDirectory = Directory.GetParent(directoryInfo.FullName);
        destDirName = System.IO.Path.Combine(parentDirectory.FullName, destDirName);

        // If the destination directory doesn't exist, create it. 
        if (!Directory.Exists(destDirName))
        {
            Directory.CreateDirectory(destDirName);
        }
        // Get the files in the directory and copy them to the new location.
        FileInfo[] files = directoryInfo.GetFiles();

        foreach (FileInfo file in files)
        {
            string tempPath = System.IO.Path.Combine(destDirName, file.Name);

            if (File.Exists(tempPath))
            {
                File.Delete(tempPath);
            }

            file.CopyTo(tempPath, false);
        }
        // If copying subdirectories, copy them and their contents to new location using recursive  function. 
        if (isCopySubDirs)
        {
            foreach (DirectoryInfo item in directories)
            {
                string tempPath = System.IO.Path.Combine(destDirName, item.Name);
                DirectoryCopy(item.FullName, tempPath, isCopySubDirs);
            }
        }
    }