我在 C# 代码中编写了以下算法,以递归方式列出文件夹中的文件。
- 开始遍历目录及其子目录中的文件列表。
- 将文件名和路径存储在列表中。
- 如果当前文件与列表中的任何其他文件匹配,则在将两个文件标记为重复时。
- 从列表中获取所有标记为重复的文件。
- 按名称分组并返回。
在包含 50,000 个文件和 12,000 个子目录的文件夹中,执行速度非常慢。由于磁盘读取操作基本上是耗时的任务。甚至LINQ.Parallel()也无济于事。
实施:
class FileTuple { public string FileName { set; get; } public string ContainingFolder { set; get; } public bool HasDuplicate { set; get; } public override bool Equals(object obj) { if (this.FileName == (obj as FileTuple).FileName) return true; return false; } }
- FileTuple 类跟踪文件名和包含目录,标志跟踪重复状态。
- 我已经覆盖了 equals 方法以仅比较 fileTuples 集合中的文件名。
以下方法查找重复文件并作为列表返回。
private List<FileTuple> FindDuplicates()
{
List<FileTuple> fileTuples = new List<FileTuple>();
//Read all files from the given path
List<string> enumeratedFiles = Directory.EnumerateFiles(txtFolderPath.Text, "*.*", SearchOption.AllDirectories).Where(str => str.Contains(".exe") || str.Contains(".zip")).AsParallel().ToList();
foreach (string filePath in enumeratedFiles)
{
var name = Path.GetFileName(filePath);
var folder = Path.GetDirectoryName(filePath);
var currentFile = new FileTuple { FileName = name, ContainingFolder = folder, HasDuplicate = false, };
int foundIndex = fileTuples.IndexOf(currentFile);
//mark both files as duplicate, if found in list
//assuming only two duplicate file
if (foundIndex != -1)
{
currentFile.HasDuplicate = true;
fileTuples[foundIndex].HasDuplicate = true;
}
//keep of track of the file navigated
fileTuples.Add(currentFile);
}
List<FileTuple> duplicateFiles = fileTuples.Where(fileTuple => fileTuple.HasDuplicate).Select(fileTuple => fileTuple).OrderBy(fileTuple => fileTuple.FileName).AsParallel().ToList();
return duplicateFiles;
}
您能否提出一种提高性能的方法。
谢谢您的帮助。