2010-08-25 48 views
2

我負責閱讀大型文本文件(大約150 MB),解析它並在數據網格中顯示記錄。該文件由括號分隔。在.NET 3.5 c中處理大型文本文件#

我正在通過 - 在一個單獨的線程中完成 - 將整個文件讀入內存,將信息存儲在數據集中,然後將數據集綁定到位於原始線程中主窗體上的數據網格。

我有兩個問題/問題:

  1. 這是做的最好的方法是什麼?正在讀取一個150MB的文件到內存大嗎?做這類工作的最佳做​​法是什麼?

  2. 爲進程分配的內存量是巨大的..這是可以理解的,因爲我正在閱讀這樣一個大文件。但是,問題是它沒有被釋放。所以如果我想要處理兩個文件,越來越多的內存將被分配。直到某個時候,程序纔會崩潰。我猜數據集對象正在被一些阻止內存分配的東西引用......有沒有辦法確定這個對象是什麼?有沒有可用於此目的的工具或方法?

對此的任何幫助將不勝感激。我從來沒有在我的編碼生涯中不得不擔心內存管理。謝謝。

+2

有一種Linq讀取線條方法,它懶惰地讀取文本行,您是否看過? – asawyer 2010-08-25 16:35:17

+0

查看代碼來診斷第二個問題會很有幫助。 – 2010-08-25 16:36:04

回答

1
  1. 這是可以接受的,如果你只讀過一個文件,並且你不希望它增長超過150MB。這裏的重要因素是,您的應用程序的用戶有足夠的內存來打開文件。 150Mb並不多,如果你達到150GB,你會遇到問題。
  2. 這是因爲您可能仍然在某處存在對內存中文件的引用。可能是因爲你在屏幕上顯示它。

如果您需要將整個內容加載到內存中,以便您的應用程序的用戶可以縮小文件,那麼您的手就會被綁定。您可以嘗試按照用戶需要的方式傳輸記錄。如果你想要走這條路,那麼TextReader和/或StreamReader類可能是一個很好的起點。

0

您可以使用unsafe關鍵字來手動分配和取消分配文件。

Alternativly使用「使用」關鍵字

using (File newFile = input.read()) { 
    // Do stuff 


} 

無可奉告數據集上

1

至於內存沒有得到釋放:如果您使用的是像一個StreamReader東西在文本閱讀,你需要在完成之後調用.Dispose()方法(或者把它放在using(){}方塊中)。這可能對GC未收集的原因產生一些影響。

對於你的第一個問題,儘管150毫克這些日子真的不是那麼多,假設你一次只做一個文本文件。在你需要多個/併發進程之前,我不會擔心它。

0

就我個人而言,我會考慮對它進行分頁,並且一次只能載入100條記錄。然後清除內存並在點擊「下一步」按鈕時加載下一個100。與搜索引擎中的搜索結果如何處理搜索引擎相似,他們可以將所有搜索結果顯示在一個頁面中,因爲它需要永久加載,因此可以將搜索結果拆分爲更小的塊。是否有任何理由需要加載所有數據?

1

首先內存問題找到一個分析器(我曾經使用JetBrains中的一個,但幾乎所有的都會這樣做)。至少會告訴你什麼是消耗內存

這可能不會解決你的具體問題我還沒有使用150MB的數據方法 但我自己的第一種方法是通常將文件包裝在一個IEnumerable每次閱讀一個條目,並懶洋洋地這樣做。

如果存在內存/性能問題(我認爲它們將適用於您的情況)我將加載部分文件(使用枚舉),並且只在顯示內容時保留該部分。 (但是,如果您需要向後導航,這會產生一個新問題)