【问题标题】:How to find and replace text in a file如何查找和替换文件中的文本
【发布时间】:2012-11-10 15:57:01
【问题描述】:

到目前为止我的代码

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 的搜索和替换功能。祝您好运

标签: c# .net io streamreader file-handling


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    这就是我对大 (50 GB) 文件的处理方式:

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

    第一种方法适用于一些 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();
        }
    

    【讨论】:

      【解决方案3】:

      这段代码对我有用

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

      【讨论】:

        【解决方案4】:

        您需要将读取的所有行写入输出文件,即使您不更改它们。

        类似:

        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。)

        【讨论】:

        • VB 必须更改 2 行:使用 input As New StreamReader(filename) While input.Peek() >= 0
        【解决方案5】:

        您可能必须将文本文件拉入内存,然后进行替换。然后,您必须使用您清楚知道的方法覆盖文件。所以你首先:

        // 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】:

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

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

          【讨论】:

          • @WinCoder BTW 对于更复杂的替换,您可以使用 Regex.Replace
          • 这会将整个文件一次读取到内存中,但并不总是那么好。
          • @Banshee Touche' 我刚尝试读取 9,000,000 行,却被抛出了 System out of memory 异常。
          • 对于大文件,这是更复杂的问题。读取字节块,分析它们,读取另一个块,等等。
          • @Alexander 对。一个以“...som”结尾,下一个以“e text...”开头。使它成为一个更复杂的问题。
          【解决方案7】:

          您将很难写入您正在读取的同一个文件。一种快速的方法是简单地这样做:

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

          【讨论】:

          • 这很简单,但不适用于非常大的文件。 (附:我不是投反对票的人)
          • 我同意,但在读取文件时不能写入文件。除非你写出一个不同的文件,然后用重命名来替换它。无论哪种方式,新文件在你构建它时必须存储在其他地方,无论是在内存中还是在磁盘上。
          • @Flynn1179 在此示例中不正确。有用。试试看。我猜ReadAllTextWriteAllText 之前关闭了文件访问。我在自己的应用程序中使用了这种技术。
          • 我知道;这个例子在阅读时不写,这就是我的意思!
          • 这是一个很好的例子,我的意思是很多人不需要将它用于大文件处理.. 我们中的一些人对使用这种直接方法的 2000 行小文件感到满意。跨度>
          猜你喜欢
          • 2017-06-28
          • 2014-03-05
          • 2020-07-29
          • 2018-12-31
          • 2013-07-18
          • 1970-01-01
          • 2014-07-05
          相关资源
          最近更新 更多