2012-11-05 88 views
5

這是切線與an earlier question of mine.使用正則表達式在文件中讀取?

本質上說,在這個問題的解決偉大的工作,但現在我需要去適應它在一個更大的分析應用工作。僅僅使用StreamReader.ReadToEnd()是不可接受的,因爲我將讀取的一些文件非常大。如果出現錯誤並且有人忘記清理,理論上它們可能是千兆字節。顯然,我不能只讀到最後。

不幸的是,正常的讀取行也是不可接受的,因爲我讀取的一些行數據包含堆棧跟蹤 - 它們顯然在其格式中使用/r/n。理想情況下,我想告訴程序向前閱讀,直到匹配正則表達式,然後返回。是否有任何功能可以在.net中執行此操作?如果沒有,我可以得到一些關於如何寫它的建議嗎?

編輯:爲了使它更容易一點跟隨我的問題,這裏有一些適應代碼的重要組成部分的貼:

foreach (var fileString in logpath.Select(log => new StreamReader(log)).Select(fileStream => fileStream.ReadToEnd())) 
{ 
    const string junkPattern = @"\[(?<junk>[0-9]*)\] \((?<userid>.{0,32})\)"; 
    const string severityPattern = @"INFO|ERROR|FATAL"; 
    const string datePattern = "^(?=[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2},[0-9]{3})"; 
    var records = Regex.Split(fileString, datePattern, RegexOptions.Multiline); 
    foreach (var record in records.Where(x => string.IsNullOrEmpty(x) == false)) 
    ...... 

問題就出在foreach。 .Select(fileStream => fileStream.ReadToEnd())會炸得不好,我只知道它。

+4

在那裏您有我不真正關心使用RegEx執行此類任務的主要原因之一。如果你寫了一個簡單的解析器,你可以簡單地修改它來處理新的行。 –

+0

@JonathanWood正則表達式對於在記錄整個記錄之後解析單個記錄非常棒。我只是彈出我需要的所有信息,並直接進入相關字段。問題是在這種情況下的文件輸入,它似乎是不夠靈活,一次給我一個單一的記錄,我有我的文件。但那似乎是假的,不是嗎?這不是一個不常見的問題。 – tmesser

+1

因此堆棧跟蹤具有/ r/n。爲什麼這會消除readline? – Paparazzi

回答

1

首先,你應該將你的const定義移動到類聲明 - 編譯器會爲你做這件事,但這應該由你自己完成,只是爲了更好的代碼可讀性。

正如@Blam提到的,你應該使用對StringBuilderStreamReader.ReadLine,這樣的事情:

foreach(var filePath in logpath) 
{ 
    var sbRecord = new StringBuilder(); 
    using(var reader = new StreamReader(filePath)) 
    { 
     do 
     { 
      var line = reader.ReadLine(); 
      // check start of the new record lines 
      if (Regex.Match(line, datePattern) && sbRecord.Length > 0) 
      { 
       // your method for log record 
       HandleRecord(sbRecord.ToString()); 
       sbRecord.Clear(); 
       sbRecord.AppendLine(line); 
      } 
      // if no lines were added or datePattern didn't hit 
      // append info about current record 
      else 
      { 
       sbRecord.AppendLine(line); 
      } 
     } while (!reader.EndOfStream) 
    } 
} 

如果我不明白一些關於您的問題,請在評論澄清這一點。
此外,您可以使用ThreadPool來安排線路的任務,只是爲了提高應用程序的速度。

+0

我最終編寫了我自己的解決方案,以低層爲基礎處理流,因爲我覺得我無法將文本流解析爲標準化的標記是絕對荒謬的。然而,對於其他人來說,這或多或少是你必須要做的。 – tmesser

+0

@YYY可能你可以在這裏提供你的代碼,只是爲了記錄?我認爲這很有趣。 – VMAtm

+0

儘管我很喜歡這樣做,但它很快就會成爲一些銀行軟件的一部分,因此是專有的。也就是說,當我休息幾天時,我的日程安排中的一件事就是製作一個開源版本並將其添加到我的github中,以便我可以擴展該解決方案。就目前而言,我基本上讀取固定數量的字節並保留一個文件位置,這在我們的項目環境中非常有用,但不是一個好的通用解決方案。一旦我複製/消毒我的初始工作並將其添加到github中,這個雄心就會繼續。 – tmesser

相關問題