2009-04-29 9 views
1

Ich habe eine App, wo ich eine Liste von Laufwerken auf dem Computer und wenn Sie eine auswählen, ich ein Baum Steuerelement mit den Verzeichnissen und Dateien bevölkern.Verzeichnisstruktur mit Linq?

Ich dachte daran, dies mit linq zu versuchen, um jedes Verzeichnis zu durchlaufen und seine untergeordneten Verzeichnisse zu erhalten.

Hat jemand so etwas schon einmal gemacht?

Dank

Antwort

2

Sie LINQ kein Problem verwenden können, obwohl es sich um eine einfach genug Aufgabe ist, dass die Dateisystembezogener Code ist wahrscheinlich länger als der LINQ-bezogene Code:

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

Nebenbei - Sie könnten daran interessiert sein zu wissen, dass .NET 4.0 LINQ-enable-Dateioperationen eingebaut (richtige faul, scheinbar - nicht über ein Array iterating). Suchen Sie nach "File System Enumeration Improvements" auf diesem BCL Team Blog Eintrag.

0

Wenn eine Benutzeroberfläche eine Baumstruktur mit Dateien und Ordnern anzeigt, wird normalerweise nicht die gesamte Hierarchie in einer einzigen Aufnahme gescannt. Stattdessen sammelt es gerade genug Informationen für die Knoten, die erweitert werden. Dann, wenn der Benutzer einen Knoten erweitert, geht es dann darum, herauszufinden, was unter diesem Knoten platziert werden muss.

Der Grund ist einfach, weil die Anzahl der Dateien und Verzeichnisse auf den Systemlaufwerken vieler Personen sehr groß werden kann, und Ihre Anwendung wird für eine Weile einfrieren, wenn sie das Stammverzeichnis von Laufwerk C: fragen.

Es hängt leicht davon ab, ob Sie WPF oder Windows Forms verwenden. In WPF befindet sich das Expanded-Ereignis auf der TreeViewItem selbst, während in Windows Forms mehrere Erweiterungsereignisse auf der TreeView (und keine Ereignisse auf TreeNode) sind. Aber das Muster ist sehr ähnlich.

Wenn Sie einen Baumknoten hinzufügen, der einen Ordner darstellt, erstellen Sie einen Dummy-Knoten darunter. Geben Sie ihm eine spezielle Kennung (ein spezielles Flag in der Tag-Eigenschaft oder möglicherweise einen eindeutigen Namen mit ungültigen Dateisystemzeichen). Dadurch kann der Benutzer diesen Knoten erweitern. Sehen Sie sich dann in Ihrem Erweiterungsereignis-Handler den ersten untergeordneten Knoten an. Wenn es sich um den speziellen Dummy-Knoten handelt, entfernen Sie ihn und erstellen Sie dann den tatsächlichen untergeordneten Knoten für diesen Knoten. Dadurch wird sichergestellt, dass Sie die realen Knoten nur einmal pro Verzeichnis sammeln.

Hier ist eine grobe Idee für 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); 
      } 
     } 
    }; 

Die _dummyTag kann nur ein Feld sein:

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

Lassen Sie mich meine tree extensions wieder pimp :)

Probe:

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

Wenn Sie GetFiles verwenden, starten Sie eine Blockierungsoperation, die ein Array zurückgibt.Wenn Sie stattdessen EnumerateFiles verwenden, erhalten Sie eine faule Auswertung, die es Ihnen ermöglicht, mit der Arbeit zu beginnen, bevor alle Dateien aus dem Dateisystem zurückgegeben wurden. Viel mehr LINQy.

Z. B .:

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