2011-08-24 218 views
3

我有一個不超過10KB的日誌文件(文件大小最大可以達到2 MB),我想查找這些文件中是否至少有一組這樣的字符串。這些字符串將在不同的線路一樣,在文件中查找字符串的最快方法

ACTION:.......

輸入:...........

結果:... .......

我至少需要知道文件中是否存在上述一組。我已經做了100次左右的測試(每次記錄不同,所以我重新加載並閱讀日誌),所以我正在尋找最快的方式來做到這一點。

我擡頭看着論壇尋找最快的方式,但我不認爲我的文件對於那些silutions來說太大了。

Thansk尋找。

+1

10 KB真的很小。我已經使用過大的文件以適應內存=/ – NullUserException

回答

3

我將逐行閱讀和檢查的條件。一旦你看到一個組,你可以退出。這樣你就不需要把整個文件讀入內存。就像這樣:

public bool ContainsGroup(string file) 
    { 
     using (var reader = new StreamReader(file)) 
     { 
      var hasAction = false; 
      var hasInput = false; 
      var hasResult = false; 
      while (!reader.EndOfStream) 
      { 
       var line = reader.ReadLine(); 
       if (!hasAction) 
       { 
        if (line.StartsWith("ACTION:")) 
         hasAction = true; 
       } 
       else if (!hasInput) 
       { 
        if (line.StartsWith("INPUT:")) 
         hasInput = true; 
       } 
       else if (!hasResult) 
       { 
        if (line.StartsWith("RESULT:")) 
         hasResult = true; 
       } 

       if (hasAction && hasInput && hasResult) 
        return true; 
      } 
      return false; 
     } 
    } 

此代碼檢查是否有開始行動,那麼一個與輸入,然後用一個結果的線。如果這些順序不重要,那麼您可以省略if() else if()檢查。如果線路沒有以字符串開頭,則用Contains替換StartsWith

+0

謝謝。我會和這一起去的。 – user393148

2

當談到效率時,您對文本文件沒有多少選擇。最簡單的方法肯定是遍歷每一行數據。當你抓住一個字符串中的一行時,將它分割在空格上。然後將這些單詞與您的單詞相匹配,直到找到匹配。然後做任何你需要的。

我不知道該怎麼做,在C#中,但在VB中它會是這樣的......

Dim yourString as string 
Dim words as string() 
Do While objReader.Peek() <> -1 
    yourString = objReader.ReadLine() 
    words = yourString.split(" ") 
    For Each word in words() 
     If Myword = word Then 
     do stuff 
     End If 
    Next 
Loop 

希望幫助

3

這裏是一個可能的方式做到這一點:

StreamReader sr; 
string fileContents; 

string[] logFiles = Directory.GetFiles(@"C:\Logs"); 

foreach (string file in logFiles) 
{ 

    using (StreamReader sr = new StreamReader(file)) 
    { 

     fileContents = sr.ReadAllText(); 

     if (fileContents.Contains("ACTION:") || fileContents.Contains("INPUT:") || fileContents.Contains("RESULT:")) 
     { 
      // Do what you need to here 
     } 

    } 
} 

您可能需要根據您的確切實施需求做一些變化 - 例如,如果該詞跨越兩行,該行是否需要以該詞開頭,那麼該怎麼辦等。

新增

備用線路逐線檢查:

StreamReader sr; 
string[] lines; 

string[] logFiles = Directory.GetFiles(@"C:\Logs"); 

foreach (string file in logFiles) 
{ 

    using (StreamReader sr = new StreamReader(file) 
    { 

     lines = sr.ReadAllLines(); 

     foreach (string line in lines) 
     {   
      if (line.Contains("ACTION:") || line.Contains("INPUT:") || line.Contains("RESULT:")) 
      { 
       // Do what you need to here 
      } 
     } 

    } 
} 
+0

逐行可能會發生錯誤。即g:「AC」「TION」可以在不同的行上(如果編碼器沒有對文本文件給予任何關注)String.Contains是最好的功能。 – icaptan

+0

@icaptan - 是的。這就是爲什麼我先做了ReadAllText示例,以防萬一關鍵字分成兩行或多行。 – Tim

+1

如果匹配文本位於兩條不同的線上,那麼它們將被新的一行字符分隔,並且它們仍然不匹配。你必須首先去掉任何換行符。 – ChrisWue

相關問題