2016-06-09 134 views
4

我有一个非常大的文件,大小几乎为2GB。我正在尝试编写一个进程来读取文件,并在没有第一行的情况下写出它。我几乎一直只能读取和写入一行,而且一次只需要一次。我可以打开它,删除第一行并在TextPad中更快地保存它,尽管这仍然非常缓慢。在C#中读取和写入非常大的文本文件

我用这个代码来获取文件中的记录数:

private long getNumRows(string strFileName) 
{ 
    long lngNumRows = 0; 
    string strMsg; 

    try 
    { 
     lngNumRows = 0; 
     using (var strReader = File.OpenText(@strFileName)) 
     { 
      while (strReader.ReadLine() != null) 
      { 
       lngNumRows++; 
      } 

      strReader.Close(); 
      strReader.Dispose(); 
     } 
    } 
    catch (Exception excExcept) 
    { 
     strMsg = "The File could not be read: "; 
     strMsg += excExcept.Message; 
     System.Windows.MessageBox.Show(strMsg); 
     //Console.WriteLine("Thee was an error reading the file: "); 
     //Console.WriteLine(excExcept.Message); 

     //Console.ReadLine(); 
    } 

    return lngNumRows; 
} 

这个只需要几秒钟才能运行。当我添加下面的代码时,需要永远运行。难道我做错了什么?为什么写这么多时间?关于如何让这个更快的任何想法?

private void ProcessTextFiles(string strFileName) 
{ 
    string strDataLine; 
    string strFullOutputFileName; 
    string strSubFileName; 
    int intPos; 
    long lngTotalRows = 0; 
    long lngCurrNumRows = 0; 
    long lngModNumber = 0; 
    double dblProgress = 0; 
    double dblProgressPct = 0; 
    string strPrgFileName = ""; 
    string strOutName = ""; 
    string strMsg; 
    long lngFileNumRows; 

    try 
    { 
     using (StreamReader srStreamRdr = new StreamReader(strFileName)) 
     { 
      while ((strDataLine = srStreamRdr.ReadLine()) != null) 
      { 
       lngCurrNumRows++; 

       if (lngCurrNumRows > 1) 
       { 
        WriteDataRow(strDataLine, strFullOutputFileName); 
       } 
      } 

      srStreamRdr.Dispose(); 
     } 
    } 
    catch (Exception excExcept) 
    { 
     strMsg = "The File could not be read: "; 
     strMsg += excExcept.Message; 
     System.Windows.MessageBox.Show(strMsg); 
     //Console.WriteLine("The File could not be read:"); 
     //Console.WriteLine(excExcept.Message); 
    } 
} 

public void WriteDataRow(string strDataRow, string strFullFileName) 
{ 
    //using (StreamWriter file = new StreamWriter(@strFullFileName, true, Encoding.GetEncoding("iso-8859-1"))) 
    using (StreamWriter file = new StreamWriter(@strFullFileName, true, System.Text.Encoding.UTF8)) 
    { 
     file.WriteLine(strDataRow); 
     file.Close(); 
    } 
} 
+6

打开和关闭输出文件要作为所述由史蒂夫和前面的例子是不是做 – Steve

+0

每一行行数?你能不能在一次打击中统计行数并把第一个排在第一位? – kenny

+0

为什么你需要计数行的任何文字写不利于 – BugFinder

回答

7

不知道有多少,这将提高性能,但肯定的是,打开和关闭输出文件,你想要写的每一行是不是一个好主意。

而是打开这两个文件只是一个时间,然后写行直接

using (StreamWriter file = new StreamWriter(@strFullFileName, true, System.Text.Encoding.UTF8)) 
using (StreamReader srStreamRdr = new StreamReader(strFileName)) 
{ 
    while ((strDataLine = srStreamRdr.ReadLine()) != null) 
    { 
     lngCurrNumRows++; 

     if (lngCurrNumRows > 1) 
      file.WriteLine(strDataRow); 
    } 
} 

你也可以去掉勾选上lngCurrNumRow进入while循环

strDataLine = srStreamRdr.ReadLine(); 
if(strDataLine != null) 
{ 
    while ((strDataLine = srStreamRdr.ReadLine()) != null) 
    { 
      file.WriteLine(strDataRow); 
    } 
} 
0

根据之前简单地使一个空读取在你机器的内存上。你可以尝试以下的(我的大文件是“d:\ savegrp.log”我有一个2GB的文件敲门约)这使用了大约6GB内存当我试图

int counter = File.ReadAllLines(@"D:\savegrp.log").Length; 
Console.WriteLine(counter); 

它确实取决于可用存储空间。 。

File.WriteAllLines(@"D:\savegrp2.log",File.ReadAllLines(@"D:\savegrp.log").Skip(1)); 
Console.WriteLine("file saved"); 
+0

我试过了File.ReadAllLines,但是我没有足够的内存来存放这个文件。 – Cass

+0

谢谢你,史蒂夫,这很有魅力。花了差不多一个小时我的方式和file.WriteLine(strDataRow);它只需要几分钟。非常感谢大家的快速响应! – Cass

+0

你把它编译成64位吗?我刚刚超过2GB文件我的记忆体使用增加到6GB – BugFinder