2010-08-10 105 views
1

我需要使用C#搜索名稱以ACCESS開頭的日誌文件的目錄(C:\ Logs)。一旦我找到一個以ACCESS開頭的文件,我需要搜索該文件並創建一個以Identity =「」開頭的字符串集合。例如,Identity =「SWN \ smithj」,因此我需要從Identity到最後一個雙引號集。在到達文件末尾之後,我需要轉到以ACCESS開頭的下一個文件。有人可以告訴我如何在C#中執行此操作嗎?以ACCESS開頭的文件搜索目錄,然後搜索該文件

非常感謝

回答

2

看起來你已經來到這裏有兩個功能:
1)像訪問名查找文件*
2)搜索這些文件,對於喜歡「標識= *」

要做到第一個,使用一個DirectoryInfo對象和GetFiles()方法,搜索模式爲「ACCESS *」。

DirectoryInfo myDir = new DirectoryInfo(dirPath); 
var files = DirectoryInfo.GetFiles("ACCESS*"); 

然後,您將遍歷這些文件尋找您需要的數據。

List<Tuple<string, string>> IdentityLines = new List<Tuple<string, string>>();//Item1 = filename, Item2 = line 
foreach(FileInfo file in files) 
{ 
    using(StreamReader sr = new StreamReader(file.FullName) //double check that file.FullName I don't remember for sure if it's right 
    { 
     while(!string.IsNullOrEmpty(string line = sr.Read()) 
     { 
      if(line.StartsWith("Identity=")) 
       IdentityLines.Add(file.FileName, line); 
     } 
    } 
} 

這沒有被編譯,所以仔細檢查它,但它應該是非常接近你需要的。

編輯:基於來自OP的評論添加了完整的解決方案。已編譯並運行。

​​
+0

嗨Allen- 行只是你的循環之前,是正確的?什麼是元組,什麼是IdentityLines? – Josh 2010-08-10 15:06:21

+0

元組是配對類型。基本上它只是用來創建兩段數據之間的相關性。它對於C#4是新手,因此如果使用3.5或更早的版本,可以用List >替換它。 IdentityLines只是我給列表的變量名。一旦你完成了你的線條的收集,你可以將它們與它們被發現的文件一起輸出。 – AllenG 2010-08-10 15:09:19

+0

@Allen - 我用List > IdentityLines;在最後一行的while循環中,我有IdentityLines.Add(file.Name,line);我得到了一個「沒有超載方法爲ADD需要兩個參數,想法? – Josh 2010-08-10 15:22:43

2

這是一個非常簡潔的方式來完成你所追求的。

public static IEnumerable<string> GetSpecificLines(this DirectoryInfo dir, string fileSearchPattern, Func<string, bool> linePredicate) 
{ 
    FileInfo[] files = dir.GetFiles(fileSearchPattern); 

    return files 
     .SelectMany(f => File.ReadAllLines(f.FullName)) 
     .Where(linePredicate); 
} 

用法:

var lines = new DirectoryInfo("C:\Logs") 
    .GetSpecificLines("ACCESS*", line => line.StartsWith("Identity=")); 
+0

非常好用的linq。我想知道是否將ReadAllLines的Where()過濾器鏈接起來更高效?例如 .SelectMany(F => File.ReadAllLines(f.FullName)。凡(linePredicate)); 這種方式在過濾之前不會將大量數據存儲在緩衝區中。 – Jacob 2010-08-10 16:38:58

+0

@Jacob:我明白你的意思了;但除非我錯了,否則確實不應該有任何區別。由於'SelectMany'和'Where'被懶惰地評估,步驟將是相同的:'File.ReadAllLines'返回的每個'string []'數組中的行將單獨枚舉,只有匹配'linePredicate'被退回。如果你通過調試器中的代碼,你會明白我的意思。 – 2010-08-10 16:49:16

+0

@Jacob :(換句話說,我要說的是,你不會在緩衝區中存儲「大量數據」 - 除了File.ReadAllLines返回的'string []'數組之外',無論如何 - 因爲Linq擴展方法提供了懶惰評估。) – 2010-08-10 16:51:01