2009-12-16 21 views
33

Sto cercando di capire il modo migliore per aprire un file esistente e sostituire tutte le stringhe che corrispondono a una stringa dichiarata con una nuova stringa, salvarla e quindi chiuderla.Aprire un file e sostituire stringhe in C#

Suggerimenti?

+0

considerare questo commento come solo un suggerimento: se si avere studio visivo, è possibile includere le cartelle nella soluzione e utilizzare la funzionalità di ricerca e sostituzione di Visual Studio. La migliore fortuna – StackOrder

risposta

74

può essere fatto in una sola riga:

File.WriteAllText("Path", Regex.Replace(File.ReadAllText("Path"), "[Pattern]", "Replacement")); 
+5

Questo caricherà l'intero file in memoria – Banshee

+1

Oneliner molto bello per modificare i file di configurazione :) – Gorgsenegger

9
using System; 
using System.IO; 
using System.Text.RegularExpressions; 

public static void ReplaceInFile(
         string filePath, string searchText, string replaceText) 
{ 

    var content = string.Empty; 
    using (StreamReader reader = new StreamReader(filePath)) 
    { 
     content = reader.ReadToEnd(); 
     reader.Close(); 
    } 

    content = Regex.Replace(content, searchText, replaceText); 

    using (StreamWriter writer = new StreamWriter(filePath)) 
    { 
     writer.Write(content); 
     writer.Close(); 
    } 
} 
+2

+1, si potrebbe voler aggiungere 'usings' allo streamreader/writer, che è la migliore pratica afaik. –

+0

È possibile sostituire lo StreamReader con File.ReadAllText e StreamWriter con File.WriteAllText. Un po 'meno codice ... Inoltre, a seconda di cosa si sta sostituendo, potrebbe essere necessario Regex.Escape searchText, o utilizzare string.Replace. –

+1

Senza leggerlo in memoria si elabora il file riga per riga. Potresti scriverlo su un nuovo file e copiarlo sul vecchio nome del file se vuoi sostituire il file. – CSharpAtl

25

Se sei leggere file di grandi dimensioni in, e si stringa per la sostituzione non può essere visualizzato spezzato su più righe, io suggerirei qualcosa come la seguente ...

private static void ReplaceTextInFile(string originalFile, string outputFile, string searchTerm, string replaceTerm) 
{ 
    string tempLineValue; 
    using (FileStream inputStream = File.OpenRead(originalFile)) 
    { 
     using (StreamReader inputReader = new StreamReader(inputStream)) 
     { 
      using (StreamWriter outputWriter = File.AppendText(outputFile)) 
      { 
       while(null != (tempLineValue = inputReader.ReadLine())) 
       { 
        outputWriter.WriteLine(tempLineValue.Replace(searchTerm,replaceTerm)); 
       } 
      } 
     } 
    } 
} 

Allora dovreste rimuovere il file originale, e rinominare il nuovo per il nome originale, ma questo è banale - come l'aggiunta di un po 'di ba errore di errore nel controllo del metodo.

Ovviamente, se il testo sostitutivo potrebbe trovarsi su due o più linee, dovresti fare un po 'di lavoro in più, ma lascerò a te il compito di capirlo. :)

+0

Vorrei abbandonare il file Usi annidati a favore di impilarli, ma penso che sia davvero solo una preferenza. Più di una nidificazione mi fa rabbrividire un po ';) –

+0

Mi piacerebbe sapere come questo codice potrebbe essere modificato per supportare i file binari. – Tomas

+0

che cosa si tratta di file enormi? https://web.archive.org/web/20140316075223/http://towardsnext.wordpress.com/2009/02/02/replace-data-in-file-c/ – Kiquenet

9

leggero miglioramento sulla risposta suggerito che non richiede Regex, e che soddisfa i requisiti della questione:

File.WriteAllText("Path", File.ReadAllText("Path").Replace("SearchString", "Replacement")); 
0
public partial class ReadAndChange : System.Web.UI.Page 
{ 
    ArrayList FolderList = new ArrayList(); 
    ArrayList FolderListSearch = new ArrayList(); 
    ArrayList FileList = new ArrayList(); 
    protected void Page_Load(object sender, EventArgs e) 
    { 
     AllFolderList("D:\\BinodBackup\\Nilesh\\14.5.2013\\Source"); 
     foreach (string Path in FolderList) 
     { 
      AllFileList(Path); 
     } 
     foreach (string Path in FileList) 
     { 
      ReplaceFile(Path, Path.Replace("Source", "EditedCode")); 
     } 

     //string SourcePath = "D:\\BinodBackup\\Nilesh\\14.5.2013\\Onesource\\Onesource\\UserManagement\\UserControls\\AddUserDetails.ascx.cs"; 
     //string ReplacePath = "D:\\AddUserDetails.ascx.cs"; 
     //ReplaceFile(SourcePath, ReplacePath); 
    } 

    private static void ReplaceFile(string SourcePath, string ReplacePath) 
    { 
     int counter = 1; 
     string line; 

     // Read the file and display it line by line. 
     System.IO.StreamReader file = new System.IO.StreamReader(SourcePath); 
     while ((line = file.ReadLine()) != null) 
     { 
      if (!(line.Contains("//"))) 
      { 
       if (line.Contains(".LogException(")) 
       { 
        //Console.WriteLine(counter.ToString() + ": " + line); 
        string[] arr = line.Split(','); 
        string stringToReplace = arr[0].Replace("LogException", "Publish") + " , " + arr[2].Trim() + " , " + arr[3].Replace(");", "").Trim() + " , " + arr[1].Trim() + ");"; 
        //File.WriteAllText(currentPath, Regex.Replace(File.ReadAllText(currentPath), line, line + " Added")); 
        File.WriteAllText(ReplacePath, File.ReadAllText(ReplacePath).Replace(line, stringToReplace)); 
        //ReplaceInFile(currentPath, line, stringToReplace); 
       } 
      } 

      counter++; 
     } 

     file.Close(); 
    } 
    private void AllFileList(string FolderPath) 
    { 
     DirectoryInfo dir = new DirectoryInfo(FolderPath); 
     DirectoryInfo[] subdir = dir.GetDirectories(); 
     if (subdir.Length > 0) 
     { 

      foreach (DirectoryInfo dr in subdir) 
      { 
       FileInfo[] files1 = dr.GetFiles(); 
       foreach (FileInfo file in files1) 
       { 
        if(file.Name.EndsWith(".cs")) 
        CheckAndAdd((file.DirectoryName + "\\" + file.Name), FileList); 
       } 

      } 
     } 
    } 

    private void AllFolderList(string FolderPath) 
    { 
     string CurFolderPatgh = FolderPath; 
     Again: 
     AddToArrayList(CurFolderPatgh); 
     DirectoryInfo dir = new DirectoryInfo(CurFolderPatgh); 
     DirectoryInfo[] subdir = dir.GetDirectories(); 

     if (subdir.Length > 0) 
     { 
      foreach (DirectoryInfo dr in subdir) 
      { 
       AddToArrayList(((System.IO.FileSystemInfo)(dir)).FullName + "\\" + dr.Name); 
      } 
     } 
     if (FolderListSearch.Count > 0) 
     { 
      foreach (string dr in FolderListSearch) 
      { 
       CurFolderPatgh = dr; 
       FolderListSearch.Remove(dr); 
       goto Again; 
      } 
     } 
    } 

    private void AddToArrayList(string FolderPath) 
    { 
     if (!(FolderList.Contains(FolderPath))) 
     { 
      CheckAndAdd(FolderPath, FolderList); 
      CheckAndAdd(FolderPath, FolderListSearch); 
     } 
    } 

    private void CheckAndAdd(string FolderPath,ArrayList ar) 
    { 
     if (!(ar.Contains(FolderPath))) 
     { 
      ar.Add(FolderPath); 
     } 
    } 

    public static void ReplaceInFile(
         string filePath, string searchText, string replaceText) 
    { 

     var content = string.Empty; 
     using (StreamReader reader = new StreamReader(filePath)) 
     { 
      content = reader.ReadToEnd(); 
      reader.Close(); 
     } 

     content = content.Replace(searchText, replaceText); 

     using (StreamWriter writer = new StreamWriter(filePath)) 
     { 
      writer.Write(content); 
      writer.Close(); 
     } 
    } 
} 
0
using System; 
using System.Collections.Generic; 
using System.Globalization; 
using System.IO; 
using System.Linq; 

namespace DevExpressFileEditing 
{ 
    class Program 
    { 
     static List<FileInfo> _files; 
     private static Dictionary<string, string> _replaceList; 

     static void Main() 
     { 
      _files = new List<FileInfo>(); 
      _replaceList = new Dictionary<string, string>(); 

      Console.WriteLine("Dark directory searching"); 
      SearchFilesInDirectories(new DirectoryInfo(@"C:\Sourcebank\Dark")); 

      Console.WriteLine("Light directory searching"); 
      SearchFilesInDirectories(new DirectoryInfo(@"C:\Sourcebank\Light")); 

      Console.WriteLine("{0} files found", _files.Count.ToString(CultureInfo.InvariantCulture)); 

      Console.WriteLine("Replace dictinary creating"); 
      CreateReplaceList(); 
      Console.WriteLine("{0} item added", _replaceList.Count.ToString(CultureInfo.InvariantCulture)); 

      Console.Write("Replacement doing"); 
      for (int i = 0; i < _files.Count; i++) 
      { 
       var fileInfo = _files[i]; 
       Console.CursorLeft = 0; 
       Console.Write("{0} of {1}", i.ToString(CultureInfo.InvariantCulture), _files.Count.ToString(CultureInfo.InvariantCulture)); 
       ReplaceInFile(fileInfo.FullName); 
      } 
      Console.CursorLeft = 0; 
      Console.Write("Replacement done"); 
     } 

     private static void SearchFilesInDirectories(DirectoryInfo dir) 
     { 
      if (!dir.Exists) return; 

      foreach (DirectoryInfo subDirInfo in dir.GetDirectories()) 
       SearchFilesInDirectories(subDirInfo); 

      foreach (var fileInfo in dir.GetFiles()) 
       _files.Add(fileInfo); 
     } 

     private static void CreateReplaceList() 
     { 
      _replaceList.Add("Color=\"#FFF78A09\"", "Color=\"{DynamicResource AccentColor}\""); 
      _replaceList.Add("Color=\"{StaticResource ColorHot}\"", "Color=\"{DynamicResource AccentColor}\""); 
      _replaceList.Add("Color=\"#FFCC0000\"", "Color=\"{DynamicResource AccentColor}\""); 
      _replaceList.Add("To=\"#FFCC0000\"", "To=\"{DynamicResource AccentColor}\""); 
      _replaceList.Add("To=\"#FFF78A09\"", "To=\"{DynamicResource AccentColor}\""); 
      _replaceList.Add("Background=\"#FFF78A09\"", "Background=\"{DynamicResource Accent}\""); 
      _replaceList.Add("Foreground=\"#FFF78A09\"", "Foreground=\"{DynamicResource Accent}\""); 
      _replaceList.Add("BorderBrush=\"#FFF78A09\"", "BorderBrush=\"{DynamicResource Accent}\""); 
      _replaceList.Add("Value=\"#FFF78A09\"", "Value=\"{DynamicResource Accent}\""); 
      _replaceList.Add("Fill=\"#FFF78A09\"", "Fill=\"{DynamicResource Accent}\""); 
     } 

     public static void ReplaceInFile(string filePath) 
     { 
      string content; 
      using (var reader = new StreamReader(filePath)) 
      { 
       content = reader.ReadToEnd(); 
       reader.Close(); 
      } 

      content = _replaceList.Aggregate(content, (current, item) => current.Replace(item.Key, item.Value)); 

      using (var writer = new StreamWriter(filePath)) 
      { 
       writer.Write(content); 
       writer.Close(); 
      } 
     } 
    } 
} 
+0

Per mostrare come utilizzare Aggrega() per sostituisci il testo usando ancora le buone pratiche, +1. – shipr