2012-11-22 13 views
100

Il mio codice finoraCome trovare e sostituire il testo in un file con C#

StreamReader reading = File.OpenText("test.txt"); 
string str; 
while ((str = reading.ReadLine())!=null) 
{ 
     if (str.Contains("some text")) 
     { 
      StreamWriter write = new StreamWriter("test.txt"); 
     } 
} 

so come trovare il testo, ma non ho idea su come sostituire il testo nel file con la mia .

+0

Considerate questo commento come solo un suggerimento: se si dispone di Visual Studio, è possibile includere le cartelle nella soluzione e utilizzare la ricerca e sostituire caratteristica di Visual Studio .Best di fortuna – StackOrder

risposta

204

Leggi tutto il contenuto del file. Sostituire con String.Replace. Scrivi di nuovo il contenuto in un file.

string text = File.ReadAllText("test.txt"); 
text = text.Replace("some text", "new value"); 
File.WriteAllText("test.txt", text); 
+3

@WinCoder * BTW * per sostituzioni più complesse è possibile utilizzare 'Regex.Replace' –

+20

Questo legge l'intero file alla memoria in una volta, non sempre così buono. – Banshee

+4

@Banshee Touche "Ho appena provato a leggere 9.000.000 di righe e ho lanciato un'eccezione di" System out of memory ". –

26

Ti sarà difficile scrivere sullo stesso file di cui stai leggendo. Un modo rapido è quello di fare semplicemente questo:

File.WriteAllText("test.txt", File.ReadAllText("test.txt").Replace("some text","some other text")); 

È possibile lay out che meglio con

string str = File.ReadAllText("test.txt"); 
str = str.Replace("some text","some other text"); 
File.WriteAllText("test.txt", str); 
+3

Questo è semplice, ma non auspicabile per file molto grande. (p.s. Io non sono quello che ha downvoted) –

+1

Sono d'accordo, ma non puoi scrivere sul file mentre stai leggendo da esso. A meno che non si scriva su un file diverso, quindi lo si sostituisce con un rinominare in seguito. In ogni caso, il nuovo file deve essere memorizzato da qualche altra parte mentre lo si sta costruendo, sia esso in memoria o su disco. – Flynn1179

7

È probabile che sarà necessario estrarre il file di testo in memoria e quindi eseguire le sostituzioni. Dovrai quindi sovrascrivere il file usando il metodo che conosci chiaramente. Quindi per prima cosa:

// Read lines from source file. 
string[] arr = File.ReadAllLines(file); 

È quindi possibile eseguire il ciclo e sostituire il testo nell'array.

var writer = new StreamWriter(GetFileName(baseFolder, prefix, num)); 
for (int i = 0; i < arr.Length; i++) 
{ 
    string line = arr[i]; 
    line.Replace("match", "new value"); 
    writer.WriteLine(line); 
} 

questo metodo consente di controllare le manipolazioni che è possibile eseguire. Oppure, si può semplicemente fare la sostituzione in una riga

File.WriteAllText("test.txt", text.Replace("match", "new value")); 

Spero che questo aiuti.

19

È necessario scrivere tutte le righe che si leggono nel file di output, anche se non le si modifica.

Qualcosa di simile:

using (var input = File.OpenText("input.txt")) 
using (var output = new StreamWriter("output.txt")) { 
    string line; 
    while (null != (line = input.ReadLine())) { 
    // optionally modify line. 
    output.WriteLine(line); 
    } 
} 

Se si desidera eseguire questa operazione in atto, allora il modo più semplice è quello di utilizzare un file di destinazione temporaneo e alla fine sostituire il file di input con l'uscita.

File.Delete("input.txt"); 
File.Move("output.txt", "input.txt"); 

(Cercando di eseguire operazioni di aggiornamento nel mezzo del file di testo è piuttosto difficile da ottenere perché avendo sempre la sostituzione della stessa lunghezza è duri trovati maggior codifiche sono larghezza variabile.)

EDIT: Più di due operazioni sui file per sostituire il file originale, meglio usare File.Replace("input.txt", "output.txt", null). (Vedere MSDN.)

+1

VB ha dovuto modificare 2 righe: Utilizzo di input As New StreamReader (nome file) While input.Peek()> = 0 – Brent

0

Ho compiuto questo utilizzando 2 modi diversi, il primo: la lettura del file in memoria e utilizzando Regex Sostituire o String Sostituire. Quindi aggiungo l'intera stringa a un file temporaneo.

Il secondo è leggendo il file temporaneo riga per riga e creando manualmente ogni riga utilizzando StringBuilder e aggiungendo ogni riga elaborata al file dei risultati.

Il primo metodo funziona bene per le sostituzioni Regex generiche, ma memorizza la memoria se si tenta di eseguire Regex.Match in un file di grandi dimensioni.

static void ProcessLargeFile() 
    { 

     if (File.Exists(outputDefsFileName)) File.Delete(outputDefsFileName); 
     if (File.Exists(defTempProc1FileName)) File.Delete(defTempProc1FileName); 
     if (File.Exists(defTempProc2FileName)) File.Delete(defTempProc2FileName); 

     string text = File.ReadAllText(inputDefsFileName, Encoding.UTF8); 

     // PROC 1 This opens entire file in memory and uses Replace and Regex Replace 

     text = text.Replace("</text>", ""); 

     text = Regex.Replace(text, @"\<ref.*?\</ref\>", ""); 

     File.WriteAllText(defTempProc1FileName, text); 

     // PROC 2 This reads file line by line and uses String.IndexOf and String.Substring and StringBuilder to build the new lines 


     using (var fileStream = File.OpenRead(defTempProc1FileName)) 
     using (var streamReader = new StreamReader(fileStream, Encoding.UTF8)) 
     { 
      string line, newdef; 

      while ((line = streamReader.ReadLine()) != null) 
      { 

       String[] arr = line.Split('\t'); 

       string def = arr[2]; 

       newdef = Util.ProcessDoubleBrackets(def); 

       File.AppendAllText(defTempProc2FileName, newdef + Environment.NewLine); 
      } 
     } 
    } 

    public static string ProcessDoubleBrackets(string def) 
    { 
     if (def.IndexOf("[[") < 0) 
      return def; 

     StringBuilder sb = new StringBuilder(); 
     ... Some processing 

     sb.Append(def.Substring(pos, i - pos)); 

     ... Some processing 
     return sb.ToString(); 
    } 
Problemi correlati