2012-11-22 119 views
100

到目前为止我的代码如何查找和替换文本文件中的用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"); 
     } 
} 

我知道如何查找的文字,但我如何用我自己的替换文件中的文本不知道。

+0

考虑这个意见,因为只有一个提示:如果您有Visual Studio中,您可以在该解决方案中的文件夹,并使用搜索和替换运气 – StackOrder

回答

204

阅读所有的文件内容。用String.Replace替换。将内容写回档案。

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

@WinCoder *顺便说一句*更复杂的替代品,你可以使用'Regex.Replace' –

+20

这一次读取整个文件到内存,并不总是那么好。 – Banshee

+4

@Banshee Touche'我试图读取9,000,000行,并抛出了'系统内存不足'异常。 –

26

你将有一个很难写你从读取相同的文件。一个快速的方法是简单地做到这一点:

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

您可以更好的把那出与

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

的视觉工作室.Best的特点这是简单的,但不理想的非常大的文件。 (p.s.我不是那个谁downvoted) –

+1

我同意,但你不能写入文件,而你正在阅读它。除非你写出不同的文件,然后用重命名替换它。无论哪种方式,新文件必须存储在别的地方,而不管它在内存中还是磁盘上。 – Flynn1179

7

很可能您必须将文本文件拖入内存然后进行替换。然后您必须使用您清楚知道的方法覆盖文件。所以你会第一个:

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

你可以循环并替换数组中的文本。

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

这个方法给你一些控制你可以做的操作。或者,你可以只做一个替换线

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

我希望这有助于。

19

你需要写你读入输出文件中的行,即使你不改变它们。

喜欢的东西:

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

如果你想在地方执行此操作,那么最简单的方法是使用一个临时的输出文件,并在年底更换输出输入文件。

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

(试图在文本文件中执行更新操作是相当难以得到正确的,因为总是有更换同长度很难给出最编码是可变宽度的。)

编辑:而不是两个文件操作来替换原始文件,最好使用File.Replace("input.txt", "output.txt", null)。 (参见MSDN。)

+1

VB必须改变2行: 使用输入为新的StreamReader(文件名)当input.Peek()> = 0 – Brent

0

我通过使用两种不同的方式中,第一完成这一点:文件读入内存,并使用正则表达式或替换字符串替换。然后我将整个字符串附加到一个临时文件。

第二个是通过读取由线临时文件线和手动构建使用StringBuilder的每行和每追加处理线的结果文件中。

第方法适用于一般的正则表达式替换,但如果您尝试做做Regex.Matches在一个大的文件它会占用内存。

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