2012-02-02 86 views
4

結果如果我要打電話Directory.GetFiles並使其返回與模式匹配的*.bin的所有文件,但我要排除的所有文件,將匹配的模式LOG#.bin其中#是不確定長度的運行計數器。有沒有辦法在將搜索過濾器傳遞到GetFiles的步驟中過濾出結果,還是必須獲取結果數組,然後刪除我想要排除的項目?排除從Directory.GetFiles

+0

'Directory.GetFiles'不具備這種能力。模式參數僅指示應該包含什麼*。一個更好的選擇可能是使用'Directory.EnumerateFiles'並在其結果中指定一個'Where'子句。 – 2012-02-02 03:30:40

回答

8

你可以使用Linq,Directory.EnumerateFiles()Where()過濾器 - 這樣你只能得到你想要的文件,剩下的就被過濾掉了。

像這樣的東西應該工作:

Regex re = new Regex(@"^LOG\d+.bin$"); 
var logFiles = Directory.EnumerateFiles(somePath, "*.bin") 
         .Where(f => !re.IsMatch(Path.GetFileName(f))) 
         .ToList(); 

正如指出Directory.EnumerateFiles需要.NET 4.0。另外一個更清潔的解決方案(花費更多的開銷)使用DirectoryInfo/EnumerateFiles(),它返回IEnumerable<FileInfo>,因此您可以直接訪問文件名和擴展名,而無需進一步解析。

+0

如果您需要使用.Net <4.0,那麼您可以使用Pinvoke來獲得類似的結果。查看:http://tom-shelton.net/index.php/2010/01/02/using-extension-methods-and-the-win32-api-to-efficiently-enumerate-the-file-system/ – 2012-02-02 03:37:12

+0

感謝我瞭解'.Where'子句,我只是想知道是否可以在沒有第二個過濾器的情況下完成。我對你的代碼做了一些小改動,因爲它與'ThisIsNotALOG0.bin'匹配,我希望它匹配。謝謝。 – 2012-02-02 15:20:01

2

有使用LINQ的解決方案:

using System; 
using System.IO; 
using System.Linq; 

namespace getfilesFilter 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var files = Directory.GetFiles(@"C:\temp", "*.bin").Select(p => Path.GetFileName(p)).Where(p => p.StartsWith("LOG")); 
      foreach (var file in files) 
      { 
       Console.WriteLine(file); 
      } 
      Console.ReadLine(); 
     } 
    } 
}