不幸的是,它们并不是你可以用来提高表现的灵丹妙药。与往常一样,这将是速度和内存之间的权衡。此外,它们还有两个方面可能缺乏性能:数据库站点和硬盘驱动器 i/o 速度。
因此,为了提高速度,我首先会提高数据库查询的性能,以确保它可以足够快地返回名称以进行搜索。因此,请确保您的查询速度很快,并且可能使用(im MS SQL case)关键字,如@987654321@,在这种情况下,您将在查询仍在运行时检索到第一个结果,您不必等到查询完成并给你一个大块的名字。
在硬盘的另一端,您可以调用Directory.GetFiles(),但此调用会阻塞,直到它遍历所有文件并返回一个包含所有文件名的大数组。这将是消耗内存的路径,第一次搜索需要一段时间,但如果您之后只处理该数组,您将获得所有连续搜索的速度改进。另一种方法是调用Directory.EnumerateFiles(),它会在每次调用时动态搜索驱动器,因此可能会为第一次搜索获得速度,但它们不会为下一次搜索发生任何内存存储,这会提高内存占用但会降低速度,因为它们在你的记忆中没有可以被搜索到的数组。另一方面,如果检测到您一遍又一遍地迭代相同的文件并且某些缓存发生在较低级别上,操作系统也会进行一些缓存。
因此,如果返回的数组不会破坏您的记忆并对此进行所有搜索,请使用Directory.GetFiles() 检查硬盘站点(如果仅文件名或完整路径,可以将其放入HashSet 以进一步提高性能取决于您从数据库中获得的信息),在另一种情况下使用 Directory.EnumerateFiles() 并希望对某些缓存最好的是操作系统。
更新
在重新阅读您的问题和 cmets 后,据我了解,您有一个类似 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);
}
我能想到的唯一进一步的性能改进是将找到的目录放入HashSet 并在检查Directory.Exists() 之前使用它来检查现有目录,但也许这不会获得任何好处,因为操作系统已经在目录查找中进行了一些缓存,然后几乎与本地缓存一样快。但是对于这些事情,您只需要衡量您的具体问题。