我想使用 Visual C# .NET 版本 3.5 将目录中的所有文件复制到目标文件夹,这可以很容易地完成(取自 this 答案):
private static void Copy(string sourceDir, string targetDir)
{
Directory.CreateDirectory(targetDir);
foreach (var file in Directory.GetFiles(sourceDir))
File.Copy(file, Path.Combine(targetDir, Path.GetFileName(file)));
foreach (var directory in Directory.GetDirectories(sourceDir))
Copy(directory, Path.Combine(targetDir, Path.GetFileName(directory)));
}
现在,这里有一个小问题:我希望它首先对所有文件进行最小排序,因此如果源路径是可移动驱动器,一段时间后被拔出,它仍然会复制大部分可能的数据。使用上层算法,如果它首先获取包含大文件的目录,然后继续获取包含许多小文件的目录,则用户有可能在软件仍在复制大文件时将其驱动器拔出,并且什么都不会留下在驱动器上,除了不完整的大文件。
我的想法是进行多个循环:首先,将每个文件路径放入一个字典中,包括其大小,然后对这个字典进行排序,然后将每个文件从源复制到目标(包括文件夹创建)。
恐怕这不是一个非常巧妙的解决方案,因为在我看来,同样的循环两次似乎不合适。另外,如果源文件夹中有太多不同的文件和子文件夹,我不确定我的字典是否可以存储那么多信息。
有没有更好的选择?
最佳答案
您可以使用更简单的方法,因为您可以获取目录子树中的所有文件,而无需使用递归。
问题的缺失部分是文件大小。可以使用 DirectoryInfo
类和 FileInfo
类获取此信息,而排序只是应用于文件序列的 Linq 指令,如下例所示。
private static void Copy(string sourceDir, string targetDir)
{
DirectoryInfo di = new DirectoryInfo(sourceDir);
foreach (FileInfo fi in di.GetFiles("*.*", SearchOption.AllDirectories).OrderBy(d => d.Length))
{
string leftOver = fi.DirectoryName.Replace(sourceDir, "");
string destFolder = Path.Combine(targetDir, leftOver);
// Because the files are listed in order by size
// we could copy a file deep down in the subtree before the
// ones at the top of the sourceDir
// Luckily CreateDirectory doesn't throw if the directory exists
// and automatically creates all the intermediate folders required
Directory.CreateDirectory(destFolder);
// Just write the intended copy parameters as a proof of concept
Console.WriteLine($"{fi.Name} with size = {fi.Length} -> Copy from {fi.DirectoryName} to {Path.Combine(destFolder, fi.Name)}");
}
}
在这个例子中,我用 Console.WriteLine 更改了 File.Copy 方法,只是为了在不复制任何内容的情况下进行概念验证,但替换是微不足道的。
另请注意,最好使用 EnumerateFiles
而不是 GetFiles
作为 explained in the MSDN documentation
关于c# - 从递归最小的目录中复制文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39678229/