2009-08-11 6 views

Antwort

9

Nach mehreren falschen Lösungen zu sehen ForEach auf einen unveränderlichen Typ wie string, indem ich denke, ich meine eigenen Beitrag würde.

Dies wird tatsächlich die erwähnte Datei lesen und schreiben. Dennoch ist es nur für kleinere Dateien, da der gesamte Inhalt im Speicher ist *.

string filename = @"C:\testfile.txt"; 
string[] fileLines = File.ReadAllLines(filename); 
fileLines = Array.ConvertAll(fileLines, l => l.Trim()); 
File.WriteAllLines(filename, fileLines); 

In der realen Welt, dann würden Sie wahrscheinlich wollen zunächst in eine andere Datei schreiben und es auf die Originaldatei umbenennen, nachdem die Operation erfolgreich war. Sonst könnten Teile der Datei verloren gehen, wenn beim Schreiben etwas schief gegangen ist.

Ad Speichernutzung:
Eigentlich wird die Datei zweimal vorübergehend in Erinnerung sein. Sie könnten das lösen, indem Sie eine normale for-Schleife anstelle von beliebigen Erweiterungsmethoden und Lambda-Ausdrücken verwenden. Ich werde diese Übung überspringen und direkt auf den ‚richtigen‘ Weg, dies für größere Dateien zu tun:

using (StreamReader reader = new StreamReader(@"D:\infile.txt")) 
using (StreamWriter writer = new StreamWriter(@"D:\outfile.txt")) 
{ 
    string line; 
    while ((line = reader.ReadLine()) != null) 
    { 
     writer.WriteLine(line.Trim()); 
    } 
} 

// Some File.Move(..) usage to rename the files 

Implementierung „ForEachLine“:
Wenn Sie eine Hilfsmethode implementieren möchten, das tut, was Sie beschreiben Sie, Sie könnten die hässliche Umbenennungslogik darin verstecken.

Die Signatur der Methode wäre so etwas wie:

public void ForEachLine(Func<string, string> func) 

und die Linie, die den Schreib tun würde nur sein:

writer.WriteLine(func(line)); 
+0

+1 funktioniert tatsächlich, mit einem Bonus der Auflistung Nachteile –

+0

Great Post - mit Lösung und Erklärung ... –

-1

Für eher kleine Dateien verwenden File.ReadAllLines (Dateiname) .ForEach (l => l.Trim())

+0

Fast. Die ReadAllLines-Methode gibt ein Zeichenfolgenarray zurück und Sie müssen eine Liste erstellen, um die ForEach-Methode zu verwenden –

+0

Da ein Zeichenfolgenarray IEnumerable implementiert, können Sie File.ReadAllLines (Dateiname) verwenden. Wählen Sie (l => l.Trim()) –

+0

Schauen Sie auf MSDN: Array.ForEach <(Of <(T>)>) – Dewfy

-1

Sie haben die System.IO.File.ReadAllLines() -Methode, die einen String zurückgibt [] (Array von Zeichenfolgen).

Das Array kann dann mit einer foreach-Schleife verwendet werden, von der Sie es in eine Liste konvertieren und die ForEach (Action) -Methode verwenden können.

dies sollte also funktionieren:

string[] logLines = System.IO.File.ReadAllLines(@"c:\temp.log"); 
logLines.ToList().ForEach(l => l.Trim()); 
+1

Das gleiche Problem hier: 'logLines' nicht wirklich ist überhaupt geändert – Thorarin

+0

Guter Punkt Ich habe nicht bemerkt, dass er es zurück in die Datei schreiben wollte –

2

Da Sie keine Textdatei anstelle ändern können (na ja, offensichtlich Sie können, aber es ist freaking nur schwer), ein solches Objekt im Grunde zentriert werden würde um ein Read-Modify-Write-System.

+0

Zustimmen d. Ich würde niemals versuchen, die Dinge an Ort und Stelle zu verändern. In diesem Fall wird garantiert, dass die Datei kompakter wird, was mehr oder weniger eine Voraussetzung ist. Es gibt keine zuverlässige Möglichkeit, sich von einem Fehler usw. zu erholen. – Thorarin

Verwandte Themen