我的目的是解析文本文件并将信息存储在各自的表中。
我必须解析大约100个文件夹,其中包含超过8000个文件,整个大小约为20GB。 当我尝试将整个文件内容存储在字符串中时,抛出了内存输出异常。
那是
using (StreamReader objStream = new StreamReader(filename))
{
string fileDetails = objStream.ReadToEnd();
}
因此我尝试了一个像
这样的逻辑 using (StreamReader objStream = new StreamReader(filename))
{
// Getting total number of lines in a file
int fileLineCount = File.ReadLines(filename).Count();
if (fileLineCount < 90000)
{
fileDetails = objStream.ReadToEnd();
fileDetails = fileDetails.Replace(Environment.NewLine, "\n");
string[] fileInfo = fileDetails.ToString().Split('\n');
//call respective method for parsing and insertion
}
else
{
while ((firstLine = objStream.ReadLine()) != null)
{
lineCount++;
fileDetails = (fileDetails != string.Empty) ? string.Concat(fileDetails, "\n", firstLine)
: string.Concat(firstLine);
if (lineCount == 90000)
{
fileDetails = fileDetails.Replace(Environment.NewLine, "\n");
string[] fileInfo = fileDetails.ToString().Split('\n');
lineCount = 0;
//call respective method for parsing and insertion
}
}
//when content is 90057, to parse 57
if (lineCount < 90000 )
{
string[] fileInfo = fileDetails.ToString().Split('\n');
lineCount = 0;
//call respective method for parsing and insertion
}
}
}
这里90,000是批量大小,可以安全处理,而不会给我的情况带来内存不足。
此过程仍需要2天以上才能完成。我观察到这是因为逐行阅读。
有没有更好的方法来解决这个问题?
先谢谢:)
答案 0 :(得分:1)
您可以使用分析器来检测性能下降的原因。在这种情况下,很明显:磁盘访问和字符串连接。
int fileLineCount = File.ReadLines(filename).Count();
表示您阅读整个文件并丢弃您已阅读的内容。那很糟糕。丢弃if (fileLineCount < 90000)
并仅保留else
。如果你按连续顺序或整个文件逐行阅读几乎没有关系,因为在任何情况下都会缓冲读取。
避免字符串连接,尤其是对于长字符串。
fileDetails = fileDetails.Replace(Environment.NewLine,&#34; \ n&#34;); string [] fileInfo = fileDetails.ToString()。分割(&#39; \ n&#39;);
真的很糟糕。您逐行阅读文件,为什么要进行此替换/拆分? File.ReadLines()
为您提供所有行的集合。只需将其传递给解析例程。
如果你能正确地做到这一点,我希望能有显着的加速。它可以通过在主处理它们时在单独的线程中读取文件来进一步优化。但这是另一个故事。