2010-10-06 17 views
6

J'ai une fonction qui saisit actuellement tous les dossiers et sous-dossiers pour vérifier les listes de contrôle d'accès pour un petit outil que je construis mais je tire mes cheveux essayer de comprendre comment limiter la profondeur qu'il peut aller. Par exemple vous avez un dossier qui va à 4 niveaux de profondeur mais je veux être capable de n'en saisir que 3 niveaux pour les ACL.Comment limiter la profondeur d'un sous-répertoire récursif Rechercher

Actuellement je l'ai codé ainsi:

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); 
    } 
} 

Il est évident que ce n'est pas aussi beau que c'était parce que je travaille sur le problème pendant un petit moment, mais si quelqu'un peut me diriger dans la bonne direction résoudre ce problème, je serais très heureux!

+0

Qu'est-ce qui ne fonctionne pas pour vous? On dirait que ce code ne compile pas - où recCount est déclaré (et pBar et Depth)? et votre (mis en commentaire) MessageBox.Show utilise counter à la place .... –

Répondre

18

Tout d'abord, éviter de déclarer le champ recCount extérieur comme une variable « globale ». Dans les scénarios récursifs, il est généralement plus facile de passer l'état le long des appels récursifs.

Ensuite, déplacez le test de profondeur du foreach pour supprimer l'interrogation inutile du système de fichiers pour les sous-répertoires. Troisièmement, placez la logique de traitement réelle au début de votre méthode, à nouveau hors de la boucle de traitement des sous-répertoires.

Votre code serait alors ressembler à:

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

Vous venez de me sauver un mal de tête après-midi! Je vous remercie! –

+0

Super d'entendre cela, je suis content que ma solution vous a aidé. –

+3

Plutôt que de passer currentDepth, ma préférence normale serait de passer depthLimit, qui décompterait plutôt que vers le haut. – supercat

5

Une méthode possible, ajoutez un champ de classe en dehors de votre méthode et une variable pour indiquer le nombre de niveaux à atteindre.

niveaux int;

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

En réalité, 'levels' ne représente pas la profondeur, mais le nombre d'appels' StepThroughDirectories'. – digEmAll

+1

L'inconvénient est que vous ne pouvez pas avoir deux appels à StepThroughDirectories en cours en même temps (puisque les niveaux devraient être partagés). Peut-être pas un problème dans cette application, mais la solution d'Ondrej Tucny est plus autonome et plus propre. –

+0

@Paul Bon point. Je n'y ai pas pensé en répondant. – jac

2

Décrémenter RECCOUNT lorsque vous revenez de StepThroughDirectories, mais ce serait mieux ...

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

Eh bien, oui, c'est la source de l'erreur que je n'ai pas remarquée au début. Cependant, la conception est un peu maladroite, donc certains refactoring pour le rendre plus lisible et gérable serait également consultatif. –

+0

Edited mon poste pour ajouter mon refacteur proposé – Les

+0

Toutes les suggestions affichées à ce jour semblent être d'accord en ce que le passage de l'état de la récursivité est une pratique recommandée, une meilleure cohésion, une diminution du couplage (aux globales). – Les