2013-10-20 17 views
0

我想從每個行上的一個字大文本文件讀取,並將所有的值到一個SQL數據庫,一個小文本文件這工作正常,但當我有一個更大的文本文件,比如說我耗盡內存的30萬行。從c#中的大文本文件中讀取導致內存泄漏

避免這種情況的最佳方法是什麼?是否有辦法只讀取文件的一部分,將其添加到數據庫中,然後將其從內存中移出並移至下一部分?

這裏是我到目前爲止的代碼:

string path = Server.MapPath("~/content/wordlist.txt"); 
    StreamReader word_stream = new StreamReader(path); 
    string wordlist = word_stream.ReadToEnd(); 
    string[] all_words = wordlist.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); 

我再通過陣列添加每個值的數據庫循環,但是當文件是大它根本不工作。

回答

4

做這樣的:

// Choose the size of the buffer according 
// to your requirements and/or available memory. 

int bufferSize = 256 * 1024 * 1024; 

string path = Server.MapPath("~/content/wordlist.txt"); 

using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read)) 
using (BufferedStream bufferedStream = new BufferedStream(stream, bufferSize)) 
using (StreamReader reader = new StreamReader(bufferedStream)) 
{ 
    while (!reader.EndOfStream) 
    { 
     string line = reader.ReadLine(); 
     ... put line into DB ... 
    } 
} 

另外,不要忘了異常處理。

+0

使用這種方法,它可以處理一個小文本文件,但與大文件我已離開頁面加載10分鐘,沒有結果 – wazzaday

+0

使用BufferedStream。我相應地更新了我的答案。這將有希望足夠快。 – elgonzo

+0

似乎稍稍加快了這一過程,但它仍需要大約3個小時才能處理所有數據並插入到數據庫中。 – wazzaday

1

嘗試與產量回歸

StreamReader r = new StreamReader(path); 
while(!r.EndOfStream) 
{ 
    string line = r.ReadLine(); 
    yield return line; 
} 

也許你看了十行產生回報他們,他們寫入數據庫,然後下一個部分。

+0

如何在每10行之後調用這個例子? – wazzaday

+0

雖然'yield'是一個漂亮的東西,但是如果在涉及** IDisposable **的場景中使用它,異常處理可能會變成一場噩夢 - 但這確實取決於源代碼的質量/結構。 – elgonzo