2016-06-09 136 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