如何使程序快速搜索文件

时间:2012-04-13 21:21:24

标签: c#

我写了一个程序,在计算机中查找特定文件,但是在获取计算机上的许多文件时遇到了缓慢和延迟

此功能正在努力获取所有文件

void Get_Files(DirectoryInfo D)
        {
            FileInfo[] Files;
            try
            {
                Files = D.GetFiles("*.*");
                foreach (FileInfo File_Name in Files)
                    listBox3.Items.Add(File_Name.FullName);
            }
            catch { }

            DirectoryInfo[] Dirs;
            try
            {
                Dirs = D.GetDirectories();
                foreach (DirectoryInfo Dir in Dirs)
                {
                    if (!(Dir.ToString().Equals("$RECYCLE.BIN")) && !(Dir.ToString().Equals("System Volume Information")))
                        Get_Files(Dir);
                }
            }
            catch { }
        }

还有另一种方法可以让所有计算机文件更快一点吗?

5 个答案:

答案 0 :(得分:2)

使用profiler查找,哪种操作最慢。然后考虑如何让它更快。否则你可以通过优化某些东西来浪费你的时间,这不是瓶颈,也不会带来你预期的加速。

在您的情况下,您可能会发现,当您第一次调用此函数时(当目录结构不在缓存中时),大部分时间将花在GetDirectories()和GetFiles()函数中。您可以预先缓存内存(或数据库)中所有文件的列表,并使用FileSystemWatcher监视文件系统中的更改,以使用新文件更新文件列表。或者您可以使用现有服务,例如Windows索引服务,但这些服务可能并非在每台计算机上都可用。

第二个瓶颈可能是向ListBox添加文件。如果添加的项目数量很大,您可以使用ListBox.BeginUpdate暂时禁用列表框的绘制,完成后,使用ListBox.EndUpdate再次启用它。这有时会导致巨大的加速。

答案 1 :(得分:1)

答案通常取决于您的操作系统。在任何情况下,您都希望构建和维护自己的文件数据库;像你的例子中的显式搜索将太昂贵和缓慢。

Linux上的标准解决方案(以及Mac OS X,如果我没有弄错的话)是维护locatedb文件,系统会定期更新该文件。如果在这些系统上运行,您的程序可以对该数据库进行查询。

答案 2 :(得分:1)

部分问题是,GetFiles方法在获取文件夹中的所有文件之前不会返回,如果您正在执行递归搜索,那么对于您递归的每个子文件夹,它将花费更长时间。

研究使用DirectoryInfo.EnumerateFile或DirectoryInfo.EnumerateFileSystemInfos

来自文档:

  

EnumerateFiles和GetFiles方法的区别如下:当你   使用EnumerateFiles,您可以开始枚举集合   返回整个集合之前的FileInfo对象;当你使用   GetFiles,你必须等待整个FileInfo对象数组   在您可以访问该数组之前返回。因此,当你是   使用许多文件和目录,EnumerateFiles可以更多   高效。

EnumerateFileSystemInfos

也是如此

您还可以查看索引服务(如果已安装并正在运行)。请参阅CodeProject上的这篇文章:

http://www.codeproject.com/Articles/19540/Microsoft-Indexing-Service-How-To

我通过谷歌搜索“如何查询MS文件系统索引”

找到了这个

答案 3 :(得分:0)

您可以枚举所有文件一次并存储列表。

但如果你不能这样做,这基本上就像它得到的一样好。你可以做两件小事:

  • 尝试使用线程。这在SSD上会好得多,但在旋转磁盘上可能会受到伤害
  • 使用DirectoryInfo.GetFileSystemEntries。这将通过一次有效的通话返回文件和目录。

答案 4 :(得分:0)

使用Directory.GetFiles()可以发现更快的性能,因为FileInfoDirectoryInfo类从文件系统获取额外信息,这比返回基于字符串的文件名要慢得多。

这是一个代码示例,可以产生大大改进的结果,并抽象从列表框中显示文件的操作中检索文件的操作。

static void Main(string[] args)
{
    var fileFinder = new FileFinder(@"c:\SomePath");
    listBox3.Items.Add(fileFinder.Files);
}

/// <summary>
/// SOLID: This class is responsible for recusing a directory to return the list of files, which are 
/// not in an predefined set of folder exclusions.
/// </summary>
internal class FileFinder
{
    private readonly string _rootPath;
    private List<string> _fileNames;
    private readonly IEnumerable<string> _doNotSearchFolders = new[] { "System Volume Information", "$RECYCLE.BIN" };

    internal FileFinder(string rootPath)
    {
        _rootPath = rootPath;
    }

    internal IEnumerable<string> Files
    {
        get
        {
            if (_fileNames == null)
            {
                _fileNames = new List<string>();
                GetFiles(_rootPath);
            }

            return _fileNames;
        }
    }

    private void GetFiles(string path)
    {
        _fileNames.AddRange(Directory.GetFiles("*.*"));

        foreach (var recursivePath in Directory.GetDirectories(path).Where(_doNotSearchFolders.Contains))
        {
            GetFiles(recursivePath);
        }
    }
}