2015-12-30 38 views
5

Ich bin neu in C#. Ich habe ein Textfeld, wo ich die Datei eingeben, um zu suchen und eine "Suche" -Taste. Auf der Uhr der Suche möchte ich, dass es die Dateien im Ordner auffüllt, aber ich bekomme den obigen Fehler. Unten ist mein Code:

string[] directories = Directory.GetDirectories(@"d:\", 
               "*", 
               SearchOption.AllDirectories); 
string file = textBox1.Text; 
DataGrid dg = new DataGrid(); 

{ 
    var files = new List<string>(); 
    foreach (DriveInfo d in DriveInfo.GetDrives().Where(x => x.IsReady)) 
     { 
     try 
     { 
      files.AddRange(Directory.GetFiles(d.RootDirectory.FullName, file , SearchOption.AllDirectories)); 
     } 
     catch(Exception ex) 
     { 
      MessageBox.Show("the exception is " + ex.ToString()); 
      //Logger.Log(e.Message); // Log it and move on 
     } 
} 

Bitte helfen Sie mir, es zu lösen. Dank

+0

Es ist offensichtlich, dass Sie nicht in diesem TRASH gehen sollen. – Hemal

+0

nur eine umfassende Suche durchführen *** alle Verzeichnisse auf d: *** führt zu ** sehr vielen Systemordnern, auf die normale Benutzerkonten keinen Zugriff haben sollten, und Sie erhalten diesen Zugriff abgelehnt. – Claies

+0

Ich habe keinen Papierkorb im Laufwerk d. Ich suche nur nach einem Ordner oder einer Datei. Ich verstehe, dass wir nicht in den Müll gehen sollen. Bitte lassen Sie mich wissen, wie ich die Suche im Müll zumindest vermeide. –

Antwort

2

Die wichtigste Regel wenn auf einen Ordner suchen, die möglicherweise unzugänglichen Unterordner enthält, ist:

Sie NICHT Verwendung SearchOption.AllDirectories!

Verwenden SearchOption.TopDirectoryOnly statt, kombiniert mit rekursive Suche für alle zugänglichen Verzeichnissen.

Mit SearchOption.AllDirectories, eine Zugriffsverletzung wird Ihre gesamte Schleife brechen, noch bevor eine Datei/Verzeichnis verarbeitet wird. Aber wenn Sie SearchOption.TopDirectoryOnly verwenden, überspringen Sie nur, was nicht zugänglich ist.

Es ist schwieriger zu verwenden Directory.GetAccessControl() pro Kind Verzeichnis überprüfen, um zu sehen, ob Sie einen Zugriff auf ein Verzeichnis vor hand haben (diese Option ist ziemlich schwer - ich empfehle es wirklich nicht, wenn Sie genau wissen, wie der Zugriff System funktioniert).

Für rekursive Suche, ich habe diesen Code für meinen eigenen Gebrauch umgesetzt:

public static List<string> GetAllAccessibleDirectories(string path, string searchPattern) { 
    List<string> dirPathList = new List<string>(); 
    try { 
     List<string> childDirPathList = Directory.GetDirectories(path, searchPattern, SearchOption.TopDirectoryOnly).ToList(); //use TopDirectoryOnly 
     if (childDirPathList == null || childDirPathList.Count <= 0) //this directory has no child 
      return null; 
     foreach (string childDirPath in childDirPathList) { //foreach child directory, do recursive search 
      dirPathList.Add(childDirPath); //add the path 
      List<string> grandChildDirPath = GetAllAccessibleDirectories(childDirPath, searchPattern); 
      if (grandChildDirPath != null && grandChildDirPath.Count > 0) //this child directory has children and nothing has gone wrong 
       dirPathList.AddRange(grandChildDirPath.ToArray()); //add the grandchildren to the list 
     } 
     return dirPathList; //return the whole list found at this level 
    } catch { 
     return null; //something has gone wrong, return null 
    } 
} 

Dies ist, wie Sie es nennen

List<string> accessibleDirs = GetAllAccessibleDirectories(myrootpath, "*"); 

Dann müssen Sie nur die Suche/fügen Sie die Dateien unter Alle zugänglichen Verzeichnisse.

Hinweis: Diese Frage ist durchaus klassische obwohl. Ich glaube, es gibt auch andere bessere Lösungen.

Und für den Fall gibt es einige Verzeichnisse, die Sie besonders, wenn Sie alle Ihre zugänglichen Verzeichnissen vermeiden wollen, können Sie auch das List Ergebnis von LINQ-Filter Teil des Namens des Verzeichnisses als Schlüsselwort (das heißt Recycle.Bins).

1

Wie Ian in seinem post angegeben hat, verwenden Sie keine rekursive Dateiauflistung (Directory.GetFiles(path, searchPattern, SearchOption.AllDirectories)) in Ihrem Fall, da die erste Ausnahme die weitere Verarbeitung stoppt.

Auch, um solche Probleme und für bessere Ergebnisse im Allgemeinen etwas zu lindern, sollten Sie dieses Programm als Administrator ausführen. Dazu können Sie mit der rechten Maustaste auf Ihre Anwendung im Windows Explorer klicken und dann die Option Run this program as an administrator auf der Registerkarte Compatibility überprüfen.

Sie sollten auch Code wie unten verwenden, um Ihre Suche durchzuführen, damit die Zwischenausnahmen nicht weiter suchen.

static void Main(string[] args) { 
    string fileToFind = "*.jpg"; 
    var files = new List<string>(); 

    foreach (DriveInfo d in DriveInfo.GetDrives().Where(x => x.IsReady)) 
     files.AddRange(FindDirectory(fileToFind, d.RootDirectory.FullName)); 
} 

/// <summary> 
/// This function returns the full file path of the matches it finds. 
/// 1. It does not do any parameter validation 
/// 2. It searches recursively 
/// 3. It eats up any error that occurs when requesting files and directories within the specified path 
/// 4. Supports specifying wildcards in the fileToFind parameter. 
/// </summary> 
/// <param name="fileToFind">Name of the file to search, without the path</param> 
/// <param name="path">The path under which the file needs to be searched</param> 
/// <returns>Enumeration of all valid full file paths matching the file</returns> 
public static IEnumerable<string> FindDirectory(string fileToFind, string path) { 

    // Check if "path" directly contains "fileToFind" 
    string[] files = null; 
    try { 
     files = Directory.GetFiles(path, fileToFind); 
    } catch { } 

    if (files != null) { 
     foreach (var file in files) 
      yield return file; 
    } 


    // Check all sub-directories of "path" to see if they contain "fileToFInd" 
    string[] subDirs = null; 
    try { 
     subDirs = Directory.GetDirectories(path); 
    } catch { } 

    if (subDirs == null) 
     yield break; 

    foreach (var subDir in subDirs) 
     foreach (var foundFile in FindDirectory(fileToFind, subDir)) 
      yield return foundFile; 
} 
Verwandte Themen