2013-11-01 4 views
1

У меня есть ситуации, когда я должен найти путь к первому файлу с именем my.exe начиная с startingdirectory & \mydir\ и углубляются по мере необходимости.
На самом деле, IO.Directory.GetFiles подходит, но мне нужно его остановить поиск после того, как первый файл будет найден как можно с FindFirstFile от WinAPI.FindFirstFile с IO.Directory.GetFiles

VB.NET

Dim findedDirectories() As String = IO.Directory.GetFiles(_ 
startingdirectory & "\mydir\", "my.exe", IO.SearchOption.AllDirectories) 

C#

string[] findedDirectories = IO.Directory.GetFiles(_ 
startingdirectory + "\\mydir\\", "my.exe", IO.SearchOption.AllDirectories); 

Можно ли остановить поиск после того, как первый файл найден таким образом, что результат функции будет string или empty string , а не string array? Или здесь лучший способ поиска первого файла в подкаталогах?

+1

возможно дубликат [Как использовать DirectoryInfo.GetFiles и он остановится после нахождения первого матча] (http://stackoverflow.com/questions/9120737/how-to-use-directoryinfo-getfiles-and-have-it-stop-after-find-the-first-match) –

+0

@AlexFilipovici На самом деле это не обман, так как здесь мы ищем один файл в каталоге. Достаточно простого вызова 'File.Exists'. –

+0

@DavidHeffernan: _... и углубится по мере необходимости ..._ –

ответ

4

Раствор как следующий один может помочь:

/// <summary> 
/// Searches for the first file matching to searchPattern in the sepcified path. 
/// </summary> 
/// <param name="path">The path from where to start the search.</param> 
/// <param name="searchPattern">The pattern for which files to search for.</param> 
/// <returns>Either the complete path including filename of the first file found 
/// or string.Empty if no matching file could be found.</returns> 
public static string FindFirstFile(string path, string searchPattern) 
{ 
    string[] files; 

    try 
    { 
     // Exception could occur due to insufficient permission. 
     files = Directory.GetFiles(path, searchPattern, SearchOption.TopDirectoryOnly); 
    } 
    catch (Exception) 
    { 
     return string.Empty; 
    } 

    // If matching files have been found, return the first one. 
    if (files.Length > 0) 
    { 
     return files[0]; 
    } 
    else 
    { 
     // Otherwise find all directories. 
     string[] directories; 

     try 
     { 
      // Exception could occur due to insufficient permission. 
      directories = Directory.GetDirectories(path); 
     } 
     catch (Exception) 
     { 
      return string.Empty; 
     } 

     // Iterate through each directory and call the method recursivly. 
     foreach (string directory in directories) 
     { 
      string file = FindFirstFile(directory, searchPattern); 

      // If we found a file, return it (and break the recursion). 
      if (file != string.Empty) 
      { 
       return file; 
      } 
     } 
    } 

    // If no file was found (neither in this directory nor in the child directories) 
    // simply return string.Empty. 
    return string.Empty; 
} 
+0

ах ... слишком поздно ;-) –

+0

Не только то, что я хочу, но работоспособно. Спасибо за код. –

2

Я думаю, что самым простым подходом было бы организовать рекурсию в подкаталоги самостоятельно с рекурсивными вызовами Directory.GetDirectories, проходя мимо SearchOption.TopDirectoryOnly. В каждом каталоге проверьте наличие файла с File.Exists.

Это фактически отражает то, как это было бы сделано в Win32 с FindFirstFile. При использовании FindFirstFile вам всегда нужно реализовать рекурсию подкаталога самостоятельно, потому что FindFirstFile не имеет ничего общего с SearchOption.AllDirectories.

+0

Тогда было бы легче (и, возможно, медленнее) фильтровать полученный массив «findedDirectories»? –

Смежные вопросы