2010-10-06 3 views
6

У меня есть функция, которая в настоящее время захватывает все папки и подпапки, чтобы проверить ACL для небольшого инструмента, который я создаю, но я вытягиваю свои волосы пытаясь понять, как ограничить глубину, на которую он может пойти. Например, у вас есть папка, которая имеет 4 уровня глубины, но я хочу иметь возможность захватить только 3 уровня для ACL.Как ограничить глубину рекурсивного поиска подкаталогов

В настоящее время я его закодированы таким образом:

private void StepThroughDirectories(string dir) 
{ 
    string[] directories = Directory.GetDirectories(dir); 
    try 
    { 
     foreach (string d in Directory.GetDirectories(dir)) 
     { 
      if (recCount < (int)Depth) 
      { 
       GetACLs(d, new DirectoryInfo(d)); 
       pBar.Value += 1; 
       //MessageBox.Show("Recursive Level: " + counter.ToString()); 
       recCount++; 
       StepThroughDirectories(d); 
      } 
      else 
      { 
       recCount--; 
      } 
     } 
    } 
    catch (System.Exception e) 
    { 
     Console.WriteLine(e.Message); 
    } 
} 

Очевидно, что это не так хорошо, как это было, потому что я работал над проблемой на некоторое время, но если кто-нибудь может мне точку в правильном направлении Решите эту проблему, я был бы очень счастлив!

+0

Что не работает для вас? Похоже, этот код не компилируется - где объявлен recCount (и pBar, и Depth)? и ваш (закомментированный) MessageBox.Show использует счетчик вместо этого. –

ответ

18

Во-первых, избежать объявить recCount поле вне как «глобальный» переменной. В рекурсивных сценариях обычно более удобно передавать состояние по рекурсивным вызовам.

Во-вторых, переместите анализ глубины из foreach, чтобы удалить ненужные запросы файловой системы для подкаталогов.

В-третьих, поместите фактическую логику обработки в начале вашего метода, снова из цикла обработки подкаталогов.

Ваш код будет выглядеть так:

void StepThroughDirectories(string dir) 
{ 
    StepThroughDirectories(dir, 0) 
} 

void StepThroughDirectories(string dir, int currentDepth) 
{ 
    // process 'dir' 
    ... 

    // process subdirectories 
    if (currentDepth < MaximumDepth) 
    { 
     foreach (string subdir in Directory.GetDirectories(dir)) 
      StepThroughDirectories(subdir, currentDepth + 1); 
    } 
} 
+0

Ты просто спас мне дневную головную боль! Спасибо! –

+0

Замечательно, что я рад, что мое решение помогло вам. –

+3

Вместо того, чтобы проходить currentDepth, моим обычным предпочтением было бы пройти depthLimit, который будет отсчитываться, а не вверх. – supercat

5

Один возможный метод, добавьте поле класса вне вашего метода и переменную, чтобы указать, сколько уровней должно пройти максимум.

int levels;

private void StepThroughDirectories(string dir, int depth) 
{ 
    levels ++; 
    if (levels > depth) 
     return; 
    string[] directories = Directory.GetDirectories(dir); 
    try 
    { ... 
+0

На самом деле 'levels' не представляет глубину, а количество вызовов' StepThroughDirectories'. – digEmAll

+1

Недостатком этого является то, что вы не можете сразу два вызова в StepThroughDirectories (так как уровни могут быть разделены). Возможно, это не проблема в этом приложении, но решение Ondrej Tucny более самодостаточно и чище. –

+0

@Paul Хорошая точка. Я не думал об этом, отвечая. – jac

2

Decrement recCount, когда вы вернетесь из StepThroughDirectories, но это было бы лучше ...

private void StepThroughDirectories(string dir, int depth) 
    { 
     if (depth < 0) 
      return; 
     string[] directories = Directory.GetDirectories(dir); 
     try 
     { 
      foreach (string d in Directory.GetDirectories(dir)) 
      { 
       // your code here 
       Console.WriteLine("{0}", d); 
       StepThroughDirectories(d, depth-1); 
      } 
     } 
     catch (System.Exception e) 
     { 
      Console.WriteLine(e.Message); 
     } 
    } 
+0

Ну, да, это источник ошибки, которую я не заметил сначала. Однако дизайн немного неуклюжий, поэтому некоторые рефакторинги, чтобы сделать его более читаемым и управляемым, также были бы полезными. –

+0

Отредактировано мое сообщение, чтобы добавить мой предложенный рефактор – Les

+0

Все предложения, опубликованные до сих пор, похоже, согласны с тем, что переход состояния вниз по рекурсии является рекомендуемой практикой, лучшей связностью, уменьшением сцепления (с глобальными). – Les

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