將目錄下檔案依副檔名和父資料夾進行分組並統計重覆次數

  • 2149
  • 0
  • 2013-09-11

將目錄下檔案依副檔名和父資料夾進行分組並統計重覆次數

DotBlogs Tags: , ,

前一篇文章可以取得目錄下,符合特定規則的檔案清單,但是我手邊的需求,還需要依副檔名分類,且統計「父資料夾\檔案名稱」重覆出現的次數,也就是如果是下述結構:

DirAAA\
    \Shared
        \leo.asmx
    \Test
        \rose.ascx
        \leo.asmx
DirBBB\
    \Shared
        \leo.asmx
    \Test
        \rose.ascx
        \wang.asmx

預期的結果必須是:

asmx:
    Shared\leo.asmx  ->  2 次
    Test\leos.asmx  -> 1 次
    Test\wang.asmx -> 1 次 
ascx:
    Test\rose.ascx  -> 2 次

所以,一樣先看 Code 吧(請注意,以下程式使用 LINQPad 的 C# Program 模式執行):


void Main()
{
    string[] files = GetDirectoryFiles(@"d:\MyDocs\Visual Studio 2008\");
    var result = GetResultApplyDistinct(files);
    result.Dump();
}

class FileGroupObject{
    public string GroupKey { get; set; }
    public int Count { get; set; }
}

IEnumerable<IGrouping<string, FileGroupObject>> GetResultApplyDistinct(string[] files)
{
    var reg = new Regex(@"^.+\\(?<FolderAndFile>\w+\\.+$)");
    var folderStartMatch = new Regex(@"^[a-zA-Z]+.*$");
    var queryDistinct = files.GroupBy (f => reg.Match(f).Result("${FolderAndFile}"))
                             .Where(f => folderStartMatch.IsMatch(f.Key))
                              .GroupBy (f => Path.GetExtension(f.Key).ToLower(), 
                                        x => new FileGroupObject() {GroupKey = x.Key, Count = x.Count()});
    return queryDistinct;
}

string[] GetDirectoryFiles(string path)
{
    string[] files = Directory.EnumerateFiles(path, ".", SearchOption.AllDirectories)
                     .Where (f => { string ext = Path.GetExtension(f).ToLower();
                                     if (".ascx".Equals(ext) || ".asmx".Equals(ext) )
                                    {
                                        return true;
                                    }
                                     return false;})
                     .OrderBy (f => Path.GetExtension(f).ToLower())
                     .ToArray();
    return files;
}

輸出結果部分截圖:

152332

程式碼流程說明:

  • 我們先透過前一篇文章說明的 GetDirectoryFiles 方法,取得檔案清單。
  • 定義一個 FileGroupObject 用來承接之後 LINQ 查詢的結果。
  • 呼叫 GetResultApplyDistinct() 方法,傳入檔案清單,即可取得結果。

GetResultApplyDistinct() 方法是這次功能的核心,重點就是裡面的 正規式和 LINQ,茲說明如下:


var reg = new Regex(@"^.+\\(?<FolderAndFile>\w+\\.+$)");

這個正規式,目的是取出「父資料夾\檔案名稱」這個值。


var folderStartMatch = new Regex(@"^[a-zA-Z]+.*$");

這個正規式目的是排除非英文字器打頭的父資料夾,原因是有些「測試\test.asmx」這類程式,要排除在本次統計資料中。


var queryDistinct = files.GroupBy (f => reg.Match(f).Result("${FolderAndFile}"))
                         .Where(f => folderStartMatch.IsMatch(f.Key))
                         .GroupBy (f => Path.GetExtension(f.Key).ToLower(), 
                                   x => new FileGroupObject() {GroupKey = x.Key, Count = x.Count()});
  1. 首先我們依檔案所屬的父資料夾做群組,透過 reg.Match(f).Result("${folder}") 取得父資料夾。
  2. 透過 folderStartMatch.IsMatch(f.Key) 排除非英文字起頭的父資料夾之檔案。
  3. 再依檔案的副檔名做群組,並重新輸出 FileGroupObject 清單。因為已經先用「父資料夾\檔案名稱」做過一次分組,所以現在透過副檔名再分組時,只要直接取得 Count,就可以列出重覆的檔案數。

--------
沒什麼特別的~
不過是一些筆記而已