2016-03-04 71 views
0

我只是想知道,如果有一個快速解決方案來獲取我的根目錄中最深的文件夾的級別。獲取最大目錄深度

可以說,我的工作與「C:\」,然後我需要一個函數,它讓我的級別數有在根目錄下的「最深」的文件夾沒有遍歷每個目錄。

+0

你怎麼知道你的根驅動器的任何文件夾的最深層次,如果你不想來遍歷它。 (由你自己或System.IO中提供的任何功能)? – grmbl

+0

問題是如果有一個函數可以幫我。我需要知道伯爵。 –

回答

1

最好的辦法是使用System.IO.DirectoryInfoGetDirectories遞歸。請務必不要使用SearchOption.AllDirectories,因爲那樣 肯定會因安全錯誤而中斷!

static List<string> directories = new List<string>(); 
     static void GetDirectories(string path) 
     { 
      try 
      { 
       foreach (var directory in Directory.GetDirectories(path)) 
       { 
        var di = new DirectoryInfo(directory); 
        directories.Add(di.FullName); 
        GetDirectories(di.FullName); 
       } 
      } 
      catch (UnauthorizedAccessException uaex) { } 
      catch (PathTooLongException ptlex) { } 
      catch (Exception ex) { } 
     } 

static void Main(string[] args) 
    { 
     var path = @"C:\"; 

     GetDirectories(path); 

     var maxLevel = directories.Max(d => d.Split('\\').Count()); 
     var deepest = directories.Select(d => new 
      { 
       Path = d, 
       Levels = d.Split('\\').Count() 
      }) 
     .OrderByDescending(d => d.Levels) 
     .First(); 

    } 

但是你會遇到對一個PathTooLongException,看看this question如何解決這個問題。

+0

但是,這隻會讓我看到C:\的所有SubDirs,還是我錯了? –

+0

等一下,我會舉個例子。 – grmbl

+0

這是我最長的(絃樂); ,,; C:\用戶\ OOO \ .atom \包\原子自耕農\ node_modules \ TSD \ node_modules \更新通知程序\ node_modules \最新版本\ node_modules \包JSON \ node_modules \拿到\ node_modules \ duplexify \ node_modules \最終的流\ node_modules \一旦\ node_modules \ wrappy \測試 – grmbl

0

我被PathTooLongException困擾以及與此想出了:

public static class DirectoryEx 
{ 
    static char driveLetter; 
    static string longPath; 
    static List<string> directories; 

    static DirectoryEx() 
    { 
     longPath = String.Empty; 
    } 

    private static char GetAvailableDrive() 
    { 
     var all = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray().Reverse(); 
     var occupied = DriveInfo.GetDrives() 
      .OrderByDescending(d => d.Name) 
      .Select(d => (char)d.Name.ToUpper().First()); 

     var free = all.Except(occupied).First(); 

     return free; 
    } 

    public static List<string> GetDirectories(string path) 
    { 
     directories = new List<string>(); 

     // recursive call 
     FindDirectories(path); 

     return directories; 
    } 

    static void FindDirectories(string path) 
    { 
     try 
     { 
      foreach (var directory in Directory.GetDirectories(path)) 
      { 
       var di = new DirectoryInfo(directory); 

       if(!String.IsNullOrEmpty(longPath)) 
        directories.Add(di.FullName.Replace(driveLetter + ":\\", longPath + "\\")); 
       else 
        directories.Add(di.FullName); 

       FindDirectories(di.FullName); 
      } 
     } 
     catch (UnauthorizedAccessException uaex) { Debug.WriteLine(uaex.Message); } 
     catch (PathTooLongException ptlex) 
     { 
      Debug.WriteLine(ptlex.Message); 

      longPath = path; 

      Task t = new Task(new Action(() => 
      { 
       CreateVirtualDrive(longPath); 
       FindDirectories(driveLetter + ":\\"); 
       DeleteVirtualDrive(); 

       longPath = String.Empty; 
      })); 

      if (!String.IsNullOrEmpty(longPath)) 
       t.RunSynchronously(); 
     } 
     catch (Exception ex) 
     { 
      Debug.WriteLine(ex.Message); 
     } 
    } 

    static void CreateVirtualDrive(string path) 
    { 
     driveLetter = GetAvailableDrive(); 

     Process.Start(new ProcessStartInfo() { 
      FileName = "cmd.exe", 
      WindowStyle = ProcessWindowStyle.Hidden, 
      Arguments = String.Format("/c subst {0}: {1}", driveLetter.ToString(), path) 
     }); 

     while (!DriveInfo.GetDrives().Select(d => d.Name.ToUpper().First()).Contains(driveLetter)) 
     { 
      System.Threading.Thread.Sleep(1); 
     } 
    } 

    static void DeleteVirtualDrive() 
    { 
     Process.Start(new ProcessStartInfo() 
     { 
      FileName = "cmd.exe", 
      WindowStyle = ProcessWindowStyle.Hidden, 
      Arguments = String.Format("/c subst {0}: /D", driveLetter.ToString()) 
     }); 

     while (DriveInfo.GetDrives().Select(d => d.Name.ToUpper().First()).Contains(driveLetter)) 
     { 
      System.Threading.Thread.Sleep(1); 
     } 
    } 
} 

用作var directories = DirectoryEx.GetDirectories("C:\\");

這將創建(使用SUBST)用於太長因此它可以每個路徑的虛擬驅動器仍然遍歷它。需要優化,可以擴展爲提供一些DirectoryInfo包裝類。

+0

哇不錯的工作:d不知道這樣的事情甚至有可能:P –

+0

不客氣,這是寫在1個走得那麼你可能想看看你是否可以改善它! ;) – grmbl