2016-06-09 25 views
4

Ich habe eine sehr große Datei, fast 2 GB groß. Ich versuche einen Prozess zu schreiben, um die Datei einzulesen und schreibe sie ohne die erste Zeile aus. Ich konnte ziemlich oft nur eine Zeile lesen und schreiben, was ewig dauert. Ich kann es öffnen, entfernen Sie die erste Zeile und speichern Sie es schneller in TextPad, obwohl das immer noch sehr langsam ist.Lesen und Schreiben sehr großer Textdateien in C#

Ich benutze diesen Code die Anzahl der Datensätze in der Datei zu erhalten:

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; 
} 

Diese nur wenige Sekunden laufen dauert. Wenn ich den folgenden Code hinzufüge, dauert es ewig. Mache ich etwas falsch? Warum fügt der Schreibvorgang so viel Zeit hinzu? Irgendwelche Ideen, wie ich das schneller machen kann?

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

Öffnen und für jede Zeile der Ausgabedatei zu schließen, die Sie nicht – Steve

+0

schreiben wollen jedes schreiben der Zeilen ist nicht wie gesagt hilft tun – kenny

+0

Warum müssen Sie rechnen die Anzahl der Zeilen? Kannst du keine Reihen zählen und den ersten Schlag mit einem Schlag ablegen? – BugFinder

Antwort

7

nicht sicher, wie viel dies die Leistung zu verbessern, aber sicher, das Öffnen und Schließen der Ausgabedatei für jede Zeile, die Sie schreiben wollen, ist keine gute Idee.

öffnen Statt beide Dateien nur einmal und dann die Leitung direkt

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); 
    } 
} 

schreiben Sie die Prüfung auch auf lngCurrNumRow einfach machen einen leeren Lese

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

Je vor dem Betreten der while-Schleife entfernen könnte auf die Erinnerung an Ihre Maschine. Sie könnten die folgende versuchen (meine große Datei war „D: \ savegrp.log“ Ich habe eine 2 GB-Datei hatte Klopfen über) Diese etwa 6 Gb Speicher verwendet, wenn ich versuchte, es

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

Es tut hängt vom Speicher zur Verfügung. von Steve und dem vorherigen Beispiel.

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

Ich habe versucht, File.ReadAllLines, aber ich habe nicht genug Speicher für diese Datei. – Cass

+0

Danke Steve, das hat wie ein Zauber funktioniert. Es hat fast eine Stunde gedauert und mit der Datei.WriteLine (strDataRow); Es dauert nur ein paar Minuten. Vielen Dank für die schnellen Antworten! – Cass

+0

Hast du es als 64bit kompiliert? meine knapp über 2GB-Datei mein Speicherverbrauch ging bis 6GB – BugFinder