任何有效的方法来解析大型文本文件和存储解析信息?

时间:2014-10-21 11:21:16

标签: file c#-4.0

我的目的是解析文本文件并将信息存储在各自的表中。

我必须解析大约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天以上才能完成。我观察到这是因为逐行阅读。

有没有更好的方法来解决这个问题?

先谢谢:)

1 个答案:

答案 0 :(得分:1)

您可以使用分析器来检测性能下降的原因。在这种情况下,很明显:磁盘访问和字符串连接。

  1. 不要多次读取文件。我们来看看您的代码。首先,行int fileLineCount = File.ReadLines(filename).Count();表示您阅读整个文件并丢弃您已阅读的内容。那很糟糕。丢弃if (fileLineCount < 90000)并仅保留else
  2. 如果你按连续顺序或整个文件逐行阅读几乎没有关系,因为在任何情况下都会缓冲读取。

    1. 避免字符串连接,尤其是对于长字符串。

      fileDetails = fileDetails.Replace(Environment.NewLine,&#34; \ n&#34;); string [] fileInfo = fileDetails.ToString()。分割(&#39; \ n&#39;);

    2. 真的很糟糕。您逐行阅读文件,为什么要进行此替换/拆分? File.ReadLines()为您提供所有行的集合。只需将其传递给解析例程。

      如果你能正确地做到这一点,我希望能有显着的加速。它可以通过在主处理它们时在单独的线程中读取文件来进一步优化。但这是另一个故事。