将文件和子目录复制到已存在文件的另一个目录中

3
我现在卡在这个问题上很长时间了。我需要从Folder1\directory1复制(更新)所有内容到Updated\directory1,覆盖相同的文件但不删除已经存在于Updated\directory1但不存在于Folder1\directory1中的文件。为了让我的问题更清晰,这是我的预期结果:
C:\Folder1\directory1
subfolder1 subtext1.txt (2KB) subfolder2 name.txt (2KB)
C:\Updated\directory1
subfolder1 subtext1.txt (1KB) subtext2.txt (2KB)
预期结果:
C:\Updated\directory1
subfolder1 subtext1.txt (2KB) <--- updated subtext2.txt (2KB) subfolder2 <--- added name.txt (2KB) <--- added
我目前正在使用Directory.Move(source, destination),但是我在目标部分遇到了麻烦,因为它的一些目标文件夹不存在。我唯一的想法是使用String.Trim来确定是否有其他文件夹,但我无法真正使用它,因为目录应该是动态的(可以有更多的子目录或更多文件夹)。我真的很困惑。你能推荐一些提示或一些代码以让我的东西移动吗?谢谢!
4个回答

3

我从msdn上获取了这个例子http://msdn.microsoft.com/zh-cn/library/cc148994.aspx,我认为这正是你所需要的。

// 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 (System.IO.Directory.Exists(targetPath){
    System.IO.Directory.CreateDirectory(targetPath);
}

2

并行快速复制一个文件夹中所有文件到另一个文件夹,无论嵌套层数如何

已在复制10万个文件时进行了测试

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
这将有助于您,这是一个通用的递归函数,因此始终合并子文件夹。
    /// <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);
            }
        }
    }

1
// 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  
    }

});

这只是一个快速的单次操作...此处未实现错误处理。

我知道这篇文章和回复已经有6年了,但是我有一个关于你上面示例的问题。你如何将源和目标引用放在App.Config文件中而不是在此页面上? - Aubrey Love
没关系,我已经解决了。只需要将“const string”行更改为以下内容即可。 "string Src_FOLDER = ConfigurationManager.AppSettings["SrcFolder"]; string Dest_FOLDER = ConfigurationManager.AppSettings["DestFolder"]; 并将目标放在“App.Config”页面中。谢谢。 - Aubrey Love

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接