2009-05-05 64 views
5

我正在使用C#(.Net 2.0),並且我有一個相當大的文本文件(平均約1600行),我需要定期檢查確保有一行文字在那裏。確保純文本文件中存在行的最有效方法

這樣做的最有效方法是什麼?我真的必須每次都將整個文件加載到內存中嗎?

是否有我可以使用的某種文件內容搜索api?

感謝您的任何幫助/建議。

回答

5

那麼,您可以隨時使用FileSystemWatcher在文件更改時爲您提供事件,這樣您只能按需掃描文件。

3

如果文本行總是相同的,那麼使用RegEx來匹配行的文本比使用String.Equals()或==匹配文本來循環文件可能更有效。

這就是說,我不知道反正在c#中找到文件中的文本,無法將文件打開到內存中並讀取行。

這個link是一個很好的使用RegEx來匹配使用c#的文件中的行的教程。

+0

此外 - 這可能是顯而易見的,但使用RegEx線不一定總是完全一樣,它只需要遵循一個可識別的模式。 – 2009-05-05 17:09:07

+0

我可能會錯過一些東西。在每一行上使用RegEx比String.Contains(),String.StartsWith()或任何其他內置字符串解析器更有效嗎?我沒有複雜的模式匹配。我正在尋找一個確切的字符串。 – 2009-05-05 17:10:21

+0

我的假設是尋找一種文字模式。 – 2009-05-05 17:13:51

1

你應該能夠剛過線環是這樣的:

String line; 
while ((line = file.ReadLine()) != null) 
{ 
    if (line matches regex blah) 
     return true; 
} 
return false; 

ReadLine方法只加載文件的一行到內存中,而不是整個文件。當循環再次運行時,對該行的唯一引用將丟失,因此,該行將在需要時進行垃圾回收。

2

這實際上取決於您對「高效」的定義。

如果你的意思是內存效率,那麼你可以使用流讀取器,這樣你一次只能在內存中有一行文本,不幸的是這比一次加載整個文件慢,可能會鎖定文件。

如果您的意思是在最短的時間內完成,那麼這是一項將從並行架構中獲得巨大收益的任務。將文件拆分成塊,並將每個塊傳遞給不同的線程進行處理。當然,這不是特別有效的CPU,因爲它可能會讓所有內核處於高水平的使用狀態。

如果您正在尋找最少量的工作,那麼您對該文件有什麼瞭解?多久更新一次?每行的前10個字符總是一樣嗎?如果您上次查看100行,是否需要再次重新掃描這些行?任何這些都可以爲時間和內存使用量創造巨大的節省。

在一天結束時,儘管沒有神奇的子彈,並且搜索文件(在最壞的情況下)是O(n)操作。


對不起,只是重新閱讀,它可能會諷刺,我不是這個意思。我只是想強調,你在某個領域取得的任何收益很可能會在其他地方失去,「效率」在這些情況下是一個非常模棱兩可的術語。

3

除非它們是非常長的線條,否則在現代計算方面1600線不是很多!文件IO將由運行時處理,並且將被緩衝,並且將非常快速,並且內存佔用空間驚人地不起眼。

只需逐行讀取文件,或使用System.IO.File.ReadAllLines(),然後查看該行是否存在例如使用整行與字符串進行比較。

這不會成爲你的瓶頸。

如果您頻繁輪詢和/或不必要地使用正則表達式,則可能會出現瓶頸。最好使用文件系統監視器,以避免在文件未更改時解析文件。

2
List<String> lines = System.IO.File.ReadAllLines(file).ToList() 
lines.Contains("foo"); 
0

我將結合一對夫婦在這裏使用的技術:

1)。在文件上設置FileSystemWatcher。設置必要的過濾器以防止誤報。您不想不必要地檢查文件。 2)。當FSW引發事件時,使用字符串fileString = File.ReadAllLines()獲取內容。 3)。使用簡單的正則表達式來查找字符串的匹配。 4)。如果匹配的索引大於-1,那麼文件包含索引中任何值的字符串。

您已經成功地避免了必須逐行解析文件,您有可能會將大量數據(儘管1600行文本幾乎沒有那麼大)載入內存。當字符串字面值超出範圍時,它將被垃圾回收器回收。

相關問題