2013-10-18 53 views
0

。哪裏出錯我忙創建文件/文件夾的索引Windows窗體應用程序VS2010(分配上大學)。出於測試目的,文件/文件夾的索引類是在一個控制檯應用程序掌握使用foreach循環lambda表達式爲無效的參數

我用下面去通過文件夾,它運行良好,並寫入到文件中指定的驅動器中的所有文件夾的名稱。我主要從msdn資源(使用遞歸方法)一起拋出它,並且因爲它不包括獲取文件夾名稱而被修改。

我想排除某些文件夾,並決定使用一個lambda表達式和列表的單詞將是最快的,雖然我可以放置一個循環,通過數組與if比較,但在我看來,這會比較慢(這不是我對c#中錯綜複雜的工作知之甚少)。我簡要了解了lambda表達式,看看我自己是否無法修復它。

這裏工作我的代碼沒有任何文件夾排除

class Program 
{ 
    static System.Collections.Specialized.StringCollection log = new System.Collections.Specialized.StringCollection(); 
    private static List<string> _excludedDirectories = new List<string>() { "Windows", "AppData", "$WINDOWS.~BT", "MSOCache", "ProgramData", "Config.Msi", "$Recycle.Bin", "Recovery", "System Volume Information", "Documents and Settings", "Perflogs" }; 

    //method to check 
    static bool isExcluded(List<string> exludedDirList, string target) 
    { 
     return exludedDirList.Any(d => new DirectoryInfo(target).Name.Equals(d)); 
    } 

    static void Main() 
    { 

     string[] drives = {"C:\\"}; 

     foreach (string dr in drives) 
     { 
      DriveInfo di = new System.IO.DriveInfo(dr); 

      // Here we skip the drive if it is not ready to be read. 
      if (di.IsReady) 
      { 
       DirectoryInfo rootDir = di.RootDirectory; 
       WalkDirectoryTree(rootDir); 
      } 
      else 
      { 
       Console.WriteLine("The drive {0} could not be read", di.Name); 
       continue; 
      } 
     } 

     // Write out all the files that could not be processed. 
     Console.WriteLine("Files with restricted access:"); 
     foreach (string s in log) 
     { 
      Console.WriteLine(s); 
     } 
     // Keep the console window open in debug mode. 
     Console.WriteLine("Press any key"); 
     Console.ReadKey(); 
    } 

    static void WalkDirectoryTree(System.IO.DirectoryInfo root) 
    { 
     FileInfo[] files = null; 
     DirectoryInfo[] subDirs = null; 
     StreamWriter filex = new System.IO.StreamWriter("test.txt", true); 

     if (filex != null) 
     { 
      filex.Close(); 
     } 

     // Process all the folders directly under the root 
     try 
     { 
      subDirs = root.GetDirectories(); 
     }// This is thrown if even one of the folders requires permissions greater than the application provides. 
     catch (UnauthorizedAccessException e) 
     { 
      log.Add(e.Message); 
     } 
     catch (System.IO.DirectoryNotFoundException e) 
     { 
      Console.WriteLine(e.Message); 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine(e.Message); 
     } 

     // Process all the files directly under the root 
     try 
     { 
      files = root.GetFiles("*.*"); 
     }// This is thrown if even one of the files requires permissions greater than the application provides. 
     catch (UnauthorizedAccessException e) 
     { 
      log.Add(e.Message); 
     } 
     catch (System.IO.DirectoryNotFoundException e) 
     { 
      Console.WriteLine(e.Message); 
     } 
     catch(Exception e) 
     { 
      Console.WriteLine(e.Message); 
     } 

     if (files != null) 
     { 
      filex = new StreamWriter("test.txt", true); 
      foreach (FileInfo fi in files) 
      { 
       // In this example, we only access the existing FileInfo object. If we 
       // want to open, delete or modify the file, then 
       // a try-catch block is required here to handle the case 
       // where the file has been deleted since the call to TraverseTree(). 
       Console.WriteLine(fi.FullName); 
       filex.WriteLine(fi.FullName); 
      } 
      filex.Close(); 
     } 

     if (subDirs != null) 
     { 
      //var filteredDirs = Directory.GetDirectories(root.Name).Where(d => !isExcluded(_excludedDirectories, d)); 
      foreach (DirectoryInfo subds in subDirs) 
      { 
       filex = new StreamWriter("test.txt", true); 
       Console.WriteLine(subds.FullName); 
       filex.WriteLine(subds.FullName); 
       filex.Close(); 

       foreach (DirectoryInfo dirInfo in subDirs) 
       { 
        // Resursive call for each subdirectory. 
        WalkDirectoryTree(dirInfo); 
       } 
      } 
      filex.Close();// Because at end filestream needs to close 
     } 
    } 
} 

所以,我想結合。哪裏(d => isExcluded(_excludedDirectories,d)!)到我的循環:

if (subDirs != null) 
     { 
      //var filteredDirs = Directory.GetDirectories(root.Name).Where(d => !isExcluded(_excludedDirectories, d)); 
      foreach (DirectoryInfo subds in subDirs.Where(d => !isExcluded(_excludedDirectories, d))) 
      { 
       filex = new StreamWriter("test.txt", true); 
       Console.WriteLine(subds.FullName); 
       filex.WriteLine(subds.FullName); 
       filex.Close(); 

       foreach (DirectoryInfo dirInfo in subDirs) 
       { 
        // Resursive call for each subdirectory. 
        WalkDirectoryTree(dirInfo); 
       } 
      } 
      filex.Close();// Because at end filestream needs to close 
     } 

問題:我得到一個錯誤,從感嘆說:「最好的重載的方法匹配具有一些無效的ARGS ...」我應該怎麼辦/變更後,我應該走簡單的路線,並使用一個循環,如果在我的循環語句寫入文件夾名稱?因爲我也明白如何做到這一點。請記住我目前的工作方式(至少嘗試)是因爲我認爲它會更優化/更快。如果它沒有這麼大的差別,讓我知道,我會用我知道的方式。

我的猜測是,我試圖把一個。凡有在foreach做了壞事,我明白爲什麼這是或可能是。

我也試過:

if (subDirs != null) 
     { 
      //var filteredDirs = Directory.GetDirectories(root.Name).Where(d => !isExcluded(_excludedDirectories, d)); 
      foreach (DirectoryInfo subds in subDirs) 
      { 
       if ((d => !isExcluded(_excludedDirectories, d))) 
       { 
       filex = new StreamWriter("test.txt", true); 
       Console.WriteLine(subds.FullName); 
       filex.WriteLine(subds.FullName); 
       filex.Close(); 

       foreach (DirectoryInfo dirInfo in subDirs) 
       { 
        // Resursive call for each subdirectory. 
        WalkDirectoryTree(dirInfo); 
       } 
       } 

      } 
      filex.Close();// Because at end filestream needs to close 
     } 

但獲取有關不能轉換蘭巴表達式bool類型的錯誤,因爲它不是委託

讓我知道,如果你想看到的其他代碼,然後我會添加它,似乎有點多。

+0

你能粘貼代碼作爲一個塊?這樣很難全部閱讀。 – Haney

+0

@ DavidH,好的,我會在這裏添加代碼 –

回答

3

的問題是在這裏:

foreach (DirectoryInfo subds in subDirs.Where(d => !isExcluded(_excludedDirectories, d))) 

子目錄是類型的DirectoryInfo的,你isExcluded接受一個字符串作爲第二個參數。

你想:

foreach (DirectoryInfo subds in subDirs.Where(d => !isExcluded(_excludedDirectories, d.Name))) 
+0

謝謝,而不是解決方法,你轉身它周圍,只是將.Name添加到D,所以它發送一個字符串參數,非常優雅 –

4

d這裏不是string,這是一個DirectoryInfo。更改isExcluded方法簽名來應對d正確的類型。

您的簽名是:

static bool isExcluded(List<string> exludedDirList, string target) 

它應該是:

static bool isExcluded(List<string> exludedDirList, DirectoryInfo target) 

而且你的方法最終會被:

//method to check 
static bool isExcluded(List<string> exludedDirList, DirectoryInfo target) 
{ 
    return exludedDirList.Any(d => target.Name.Equals(d)); 
} 
+1

感謝您的快速回復。只是,我想我修好了,在isExcluded return exludedDirList.Any(d => new DirectoryInfo(target).Name.Equals(d));需要改變以返回exludedDirList.Any(d => new DirectoryInfo(target.FullName).Name.Equals(d));? –

+0

不知道我明白你在問什麼。看起來你對LINQ並不是很熟悉,所以我建議你閱讀它是如何推斷參數類型的,比如你的'd' – Haney

+0

因爲DirectoryInfo(target)現在不能工作,因爲它不再是一個字符串了,目標是一個DirectoryInfo。所以它需要更改爲DirectoryInfo(target.Name或target.FullName,但我更喜歡.Name)請參閱Baldrick的回答,無論如何這兩種解決方案都非常棒,至少對我來說 –

相關問題