2013-10-20 16 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