2009-04-29 5 views
1

J'ai une application où j'obtiens une liste de lecteurs sur l'ordinateur et quand vous en sélectionnez un, je remplis un contrôle d'arbre avec les répertoires et les fichiers.Obtenir la structure de répertoire à l'aide de Linq?

Je pensais essayer ceci en utilisant linq pour boucler chaque répertoire et obtenir ses répertoires enfants.

Est-ce que quelqu'un a déjà fait quelque chose comme ça?

Merci

Répondre

2

Vous pouvez utiliser LINQ pas de problème, bien que ce soit une tâche assez simple que la le code lié au système de fichiers est susceptible d'être plus long que le code lié à LINQ:

private static TreeNode AddDirectory(DirectoryInfo directory) 
{ 
    DirectoryInfo[] subdirs = directory.GetDirectories(); 
    FileInfo[] files = directory.GetFiles(); 
    IEnumerable<TreeNode> subdirNodes = from subdir in subdirs select AddDirectory(subdir); 
    IEnumerable<TreeNode> fileNodes = from file in files select new TreeNode(file.Name); 
    return new TreeNode(
     directory.Name, 
     subdirNodes.Concat(fileNodes).ToArray()); 
} 
1

En aparté - vous serez peut-être intéressé de savoir que .NET 4.0 est en train d'incorporer les opérations de fichiers LINQ-enable (celles paresseuses appropriées, apparemment - ne pas s'arrêter sur un tableau). Recherchez "Améliorations de l'énumération du système de fichiers" sur cette entrée BCL Team Blog.

0

Généralement, lorsqu'une interface utilisateur affiche une arborescence de fichiers et de dossiers, elle n'analyse pas toute la hiérarchie en une seule fois. Au lieu de cela, il rassemble juste assez d'informations pour les nœuds qui sont développés. Ensuite, lorsque l'utilisateur développe un nœud, il va alors chercher à savoir ce qui doit être placé sous ce nœud. La raison en est simplement que le nombre de fichiers et de répertoires sur les lecteurs système de beaucoup de gens peut devenir très important, et donc votre application va geler pendant un petit moment s'ils demandent à voir la racine du lecteur C :.

Il est légèrement différent selon que vous utilisez WPF ou Windows Forms. Dans WPF, l'événement Expanded est sur le TreeViewItem lui-même, alors que dans Windows Forms, il existe plusieurs événements d'expansion sur le TreeView (et aucun événement sur TreeNode). Mais le modèle est sensiblement le même.

Lorsque vous ajoutez un nœud d'arborescence qui représente un dossier, créez un nœud factice en dessous. Donnez-lui une identification spéciale (un drapeau spécial dans la propriété Tag, ou peut-être un nom unique qui contient des caractères de système de fichiers non-valides). Cela permettra à l'utilisateur de développer ce noeud. Ensuite, dans votre gestionnaire d'événements d'expansion, regardez le premier nœud enfant - s'il s'agit du nœud factice spécial, supprimez-le puis créez l'ensemble réel des nœuds enfants pour ce nœud. Cela garantira que vous ne rassemblez les nœuds réels qu'une seule fois par répertoire.

est ici une idée approximative pour WPF:

TreeViewItem folderNode = new TreeViewItem { Header = Path.GetFileName(folderPath) }; 
parentNode.Items.Add(folderNode); 

// create the dummy item under it 
TreeViewItem dummy = new TreeViewItem { Tag = _dummyTag }; 
folderNode.Items.Add(dummy); 

folderNode.Expanded += delegate 
    { 
     if (folderNode.Items.Count == 1) 
     { 
      if (((TreeViewItem)folderNode.Items[0]).Tag == _dummyTag) 
      { 
       folderNode.Items.Clear(); 
       CreateFolderChildren(folderNode, folderPath); 
      } 
     } 
    }; 

Le _dummyTag peut juste être un champ:

private static readonly object _dummyTag = new object(); 
0

Permettez-moi Pimp my tree extensions again :)

Exemple:

var di = new DirectoryInfo("foo"); 
var q = di.TraverseDepthFirst(x => x.GetFiles(), x => x.GetDirectories()); 
var nq = from fs in q 
     from f in fs 
     select f; 

foreach (FileInfo dirfiles in nq) 
{ 
    ... 
} 
0

Si vous utilisez GetFiles, vous allez démarrer une opération de blocage qui retournera un tableau.Si vous utilisez plutôt EnumerateFiles, vous obtenez une évaluation paresseuse, ce qui vous permet de commencer à travailler avant que tous les fichiers aient été renvoyés depuis le système de fichiers. Beaucoup plus LINQy.

.: par exemple

var files = directory.EnumerateFiles(); 
foreach (var file in files) 
{ 
    // do stuff 
} 
Questions connexes