如何使用C#查找和替换文件中的文本


157

到目前为止我的代码

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

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


将此注释仅作为提示:如果您有Visual Studio,则可以在解决方案中包括文件夹,并使用Visual Studio的搜索和替换功能。祝您好运
StackOrder

Answers:


321

读取所有文件内容。用替换String.Replace。将内容写回到文件中。

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

5
@WinCoder BTW,您可以使用更复杂的替代品Regex.Replace
Sergey Berezovskiy

35
这会立即将整个文件读取到内存中,并不总是那么好。
2015年

6
@Banshee Touche'我刚刚尝试读取9,000,000行,并被抛出System out of memory异常。
Squ1rr3lz 2015年

4
对于大文件,这是更复杂的问题。读取字节块,对其进行分析,再读取另一个块,等等
Alexander

6
@亚历山大权利。一块以“ ... som”结尾,下一块以“ e text ...”开头。使其成为一个更加复杂的问题。
2013年

36

您将很难写入要读取的相同文件。一种快速的方法是简单地执行此操作:

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
这很简单,但对于非常大的文件而言并不理想。(请注意,我不是被否决的人)
Alvin Wong

3
我同意,但是当您从文件中读取文件时,您将无法写入该文件。除非您写出一个不同的文件,否则在以后用重命名替换它。.无论哪种方式,新文件在构建时都必须存储在其他位置,无论是在内存中还是在磁盘上。
Flynn1179

@ Flynn1179在此示例中不正确。有用。试试看。我猜是在ReadAllText关闭文件访问之前WriteAllText。我在自己的应用程序中使用了这种技巧。
SteveCinq '18年

我知道; 这个例子在阅读时没有写,这就是我的意思!
Flynn1179 '18

27

您需要将读取的所有行写到输出文件中,即使您不进行更改也是如此。

就像是:

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行:在input.Peek()> = 0时使用输入作为新StreamReader(filename)
Brent

8

您可能必须将文本文件拉入内存,然后进行替换。然后,您将不得不使用清楚知道的方法来覆盖文件。因此,您首先需要:

// 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"));

我希望这有帮助。


6

这是我使用大文件(50 GB)的方法:

我尝试了两种不同的方法:第一种,将文件读取到内存中,并使用Regex Replace或String Replace。然后,我将整个字符串附加到一个临时文件中。

第一种方法对某些Regex替换效果很好,但是如果在一个大文件中进行多次替换,Regex.Replace或String.Replace可能会导致内存不足错误。

第二种方法是逐行读取临时文件,并使用StringBuilder手动构建每行并将每条处理过的行附加到结果文件中。这种方法非常快。

static void ProcessLargeFile()
{
        if (File.Exists(outFileName)) File.Delete(outFileName);

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

        // EX 1 This opens entire file in memory and uses Replace and Regex Replace --> might cause out of memory error

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

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

        File.WriteAllText(outFileName, text);




        // EX 2 This reads file line by line 

        if (File.Exists(outFileName)) File.Delete(outFileName);

        using (var sw = new StreamWriter(outFileName))      
        using (var fs = File.OpenRead(inFileName))
        using (var sr = new StreamReader(fs, Encoding.UTF8)) //use UTF8 encoding or whatever encoding your file uses
        {
            string line, newLine;

            while ((line = sr.ReadLine()) != null)
            {
              //note: call your own replace function or use String.Replace here 
              newLine = Util.ReplaceDoubleBrackets(line);

              sw.WriteLine(newLine);
            }
        }
    }

    public static string ReplaceDoubleBrackets(string str)
    {
        //note: this replaces the first occurrence of a word delimited by [[ ]]

        //replace [[ with your own delimiter
        if (str.IndexOf("[[") < 0)
            return str;

        StringBuilder sb = new StringBuilder();

        //this part gets the string to replace, put this in a loop if more than one occurrence  per line.
        int posStart = str.IndexOf("[[");
        int posEnd = str.IndexOf("]]");
        int length = posEnd - posStart;


        // ... code to replace with newstr


        sb.Append(newstr);

        return sb.ToString();
    }

0

这段代码对我有用

- //-------------------------------------------------------------------
                           // Create an instance of the Printer
                           IPrinter printer = new Printer();

                           //----------------------------------------------------------------------------
                           String path = @"" + file_browse_path.Text;
                         //  using (StreamReader sr = File.OpenText(path))

                           using (StreamReader sr = new System.IO.StreamReader(path))
                           {

                              string fileLocMove="";
                              string newpath = Path.GetDirectoryName(path);
                               fileLocMove = newpath + "\\" + "new.prn";



                                  string text = File.ReadAllText(path);
                                  text= text.Replace("<REF>", reference_code.Text);
                                  text=   text.Replace("<ORANGE>", orange_name.Text);
                                  text=   text.Replace("<SIZE>", size_name.Text);
                                  text=   text.Replace("<INVOICE>", invoiceName.Text);
                                  text=   text.Replace("<BINQTY>", binQty.Text);
                                  text = text.Replace("<DATED>", dateName.Text);

                                       File.WriteAllText(fileLocMove, text);



                               // Print the file
                               printer.PrintRawFile("Godex G500", fileLocMove, "n");
                              // File.WriteAllText("C:\\Users\\Gunjan\\Desktop\\new.prn", s);
                           }

0

我倾向于尽可能多地使用简单的前向代码,下面的代码对我来说很好用

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

/// <summary>
/// Replaces text in a file.
/// </summary>
/// <param name="filePath">Path of the text file.</param>
/// <param name="searchText">Text to search for.</param>
/// <param name="replaceText">Text to replace the search text.</param>
static public void ReplaceInFile( string filePath, string searchText, string replaceText )
{
    StreamReader reader = new StreamReader( filePath );
    string content = reader.ReadToEnd();
    reader.Close();

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

    StreamWriter writer = new StreamWriter( filePath );
    writer.Write( content );
    writer.Close();
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.