![](/img/trans.png)
[英]Recursively delete files from a Directory but keeping the dir structure intact
[英]Copy files from directory recursively smallest first
我想所有目錄中的文件復制到使用Visual C#.NET版本3.5中的目標文件夾,它可以很容易地完成(取自此答案):
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
如MSDN文檔中所述
我希望這有幫助!
第一; 從源目錄獲取所有文件,遞歸是可選的。 然后繼續將按大小排序的所有文件復制到目標目錄。
void CopyFiles(string sourceDir, string targetDir, bool recursive = false)
{
foreach (var file in GetFiles(sourceDir, recursive).OrderBy(f => f.Length))
{
var subDir = file.DirectoryName
.Replace(sourceDir, String.Empty)
.TrimStart(Path.DirectorySeparatorChar);
var fullTargetDir = Path.Combine(targetDir, subDir);
if (!Directory.Exists(fullTargetDir))
Directory.CreateDirectory(fullTargetDir);
file.CopyTo(Path.Combine(fullTargetDir, file.Name));
}
}
IEnumerable<FileInfo> GetFiles(string directory, bool recursive)
{
var files = new List<FileInfo>();
if (recursive)
{
foreach (var subDirectory in Directory.GetDirectories(directory))
files.AddRange(GetFiles(subDirectory, true));
}
foreach (var file in Directory.GetFiles(directory))
files.Add(new FileInfo(file));
return files;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.