不幸的是,它们并不是你可以用来提高表现的灵丹妙药。与往常一样,这将是速度和内存之间的权衡。它们还有两个可能缺乏性能的方面:数据库站点和硬盘驱动器 i/o 速度。
因此,为了提高速度,我将首先提高数据库查询的性能,以确保它可以足够快地返回名称以进行搜索。因此,请确保您的查询速度很快,并且可能使用(im MS SQL case)关键字,例如READ SEQUENTIAL
在这种情况下,您将在查询仍在运行时检索到第一个结果,您不必等到查询完成并给您大块的名字。
在硬盘的另一端,您可以调用Directory.GetFiles()
,但此调用会阻塞,直到它遍历所有文件并返回一个包含所有文件名的大数组。这将是内存消耗路径,第一次搜索需要一段时间,但如果您之后只处理该数组,您将获得所有连续搜索的速度改进。另一种方法是调用Directory.EnumerateFiles()
这将在每次调用时即时搜索驱动器,因此可能会为第一次搜索获得速度,但它们不会为下一次搜索发生任何内存存储,这会提高内存占用但会降低速度,因为它们不是内存中可以搜索的数组。另一方面,如果检测到您一遍又一遍地迭代相同的文件并且某些缓存发生在较低级别,则操作系统也会进行一些缓存。
因此,Directory.GetFiles()
如果返回的数组不会破坏您的记忆并对此进行所有搜索(HashSet
如果仅文件名或完整路径取决于您从数据库中获得的内容,则可能将其放入 a 以进一步提高性能)在另一种情况下,使用Directory.EnumerateFiles()
并希望最好的缓存是操作系统。
更新
重新阅读您的问题和评论后,据我了解,您有一个类似的名称1234567891_w.jpg
,但您不知道名称的哪个部分代表目录部分。因此,在这种情况下,您需要进行显式搜索,因为遍历所有目录只需要很长时间。这是一些示例代码,它应该让您了解如何在第一时间解决这个问题:
string rootDir = @"D:\RootDir";
// Iterate over all files reported from the database
foreach (var filename in databaseResults)
{
var fullPath = Path.Combine(rootDir, filename);
// Check if the file exists within the root directory
if (File.Exists(Path.Combine(rootDir, filename)))
{
// Report that the file exists.
DoFileFound(fullPath);
// Fast exit to continue with next file.
continue;
}
var directoryFound = false;
// Use the filename as a directory
var directoryCandidate = Path.GetFileNameWithoutExtension(filename);
fullPath = Path.Combine(rootDir, directoryCandidate);
do
{
// Check if a directory with the given name exists
if (Directory.Exists(fullPath))
{
// Check if the filename within this directory exists
if (File.Exists(Path.Combine(fullPath, filename)))
{
// Report that the file exists.
DoFileFound(fullPath);
directoryFound = true;
}
// Fast exit, cause we looked into the directory.
break;
}
// Is it possible that a shorter directory name
// exists where this file exists??
// If yes, we have to continue the search ...
// (Alternative code to the above one)
////// Check if a directory with the given name exists
////if (Directory.Exists(fullPath))
////{
//// // Check if the filename within this directory exists
//// if (File.Exists(Path.Combine(fullPath, filename)))
//// {
//// // Report that the file exists.
//// DoFileFound(fullPath);
//// // Fast exit, cause we found the file.
//// directoryFound = true;
//// break;
//// }
////}
// Shorten the directory name for the next candidate
directoryCandidate = directoryCandidate.Substring(0, directoryCandidate.Length - 1);
} while (!directoryFound
&& !String.IsNullOrEmpty(directoryCandidate));
// We did our best but we found nothing.
if (!directoryFound)
DoFileNotAvailable(filename);
}
我能想到的唯一进一步的性能改进是将找到的目录放入 aHashSet
并在检查之前Directory.Exists()
使用它来检查现有目录,但也许这不会获得任何好处,因为操作系统已经在目录查找中进行了一些缓存和然后几乎与您的本地缓存一样快。但是对于这些事情,你只需要衡量你的具体问题。