C#逐行读取文本文件并编辑特定行

5

我希望能够逐行读取文本文件并编辑特定行。所以,我已经将文本文件放入一个字符串变量中:

string textFile = File.ReadAllText(filename);

我的文本文件如下:

Line A
Line B
Line C
Line abc
Line 1
Line 2
Line 3

我有一个特定的字符串(="abc"),我想在这个文本文件中搜索它。因此,我会读取行,直到找到该字符串,并跳转到该字符串后的第三行(“Line 3” -> 此行始终不同):

string line = "";
string stringToSearch = "abc";

using (StringReader reader = new StringReader(textFile))
{
    while ((line = reader.ReadLine()) != null)
    {
        if (line.Contains(stringToSearch))
        {
            line = reader.ReadLine();
            line = reader.ReadLine();
            line = reader.ReadLine();

            //line should be cleared and put another string to this line.
        }
    }
}

我想清除第三行的内容并将另一个字符串放到该行,并将整个string保存到textFile中。

我应该怎么做?


这可能会有所帮助:File.ReadAllLines。使用它,循环遍历所有行,替换您想要替换的行,然后将其写回原始文件即可。 - Tamás Szabó
4个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
5

您可以将内容存储在 StringBuilder 中,如下所示:

StringBuilder sbText = new StringBuilder();
using (var reader = new System.IO.StreamReader(textFile)) {
    while ((line = reader.ReadLine()) != null) {
        if (line.Contains(stringToSearch)) {
            //possibly better to do this in a loop
            sbText.AppendLine(reader.ReadLine());
            sbText.AppendLine(reader.ReadLine());

            sbText.AppendLine("Your Text");
            break;//I'm not really sure if you want to break out of the loop here...
        }else {
            sbText.AppendLine(line);
        }
    }
}  
然后像这样写回去:
using(var writer = new System.IO.StreamWriter(@"link\to\your\file.txt")) {
    writer.Write(sbText.ToString());
}

如果你只是想将它存储在字符串textFile中,可以这样做:

textFile = sbText.ToString();

非常感谢!这似乎是正确的方法。现在,我只有一个问题,就是在将字符串写回“textFile”字符串时出现错误。“路径中有非法字符”,以下是代码中的一行: using(var writer = new System.IO.StreamWriter(textFile)) { - Giovanni19
@Giovanni19:我的错误,“textFile”应该是“您要写入的文本文件的链接”。我看到您在帖子中以不同的方式使用了变量。如果您只想将其存储为字符串在textFile中,您可以使用:textFile = sbText.ToString()。我已更新答案。 - waka
谢谢。但是这会将新行添加到已经有字符串“abc”的那一行。我想要将新行添加到字符串“abc”之后的第三行。 - Giovanni19
@Giovanni19:我已经更新了答案。现在它应该能够按照你想要的方式工作了。 ;) - waka

2
重新编写整个文件可能更容易:
string old  = "abc";
string nw   = "aa";
int counter = 0;

using(StreamWriter w = new StreamWriter("newfile")
{
    foreach(string s in File.ReadLines(path))
        w.WriteLine(s == old ? nw : s);
}

1
现在替换了行abc,这不是OP想要的。另外,new是一个关键字,不能用作变量名。 - waka
另外,using必须小写,必须有大括号,并且不能使用if (foo = value),因为它不会评估为bool(在某些语言中如C++会更改foo的值并导致奇怪的错误)。您必须使用if (foo == value)。此外,nw是一个可怕的变量名。为什么不使用newValue或其他描述性的名称? - AustinWBryan

2
您可能需要类似以下内容的东西:
DirectoryInfo di = new DirectoryInfo(Location);
FileInfo[] rgFiles = di.GetFiles("txt File");

foreach (FileInfo fi in rgFiles)
{
    string[] alllines = File.ReadAllLines(fi.FullName);

    for (int i = 0; i < alllines.Length; i++)
    {
        if (alllines[i].Contains(stringToSearch))
        {                        
            alllines[i] = alllines[i].Replace(stringToSearch, some value );
        }
    }
}
这样,您将逐行读取文本文件,直到文档末尾,如果检测到该值,则将其替换为新值。

这不是我想要的:/ 请看我的第一篇帖子。 - Giovanni19
@Giovanni19,您想逐行读取文档并更新值(如果找到该值),然后您想更新此值?我说得对吗?上述代码将适用于此...您是想保存此文档的新版本吗? - user8494405

2

这里是一个完整的例子:

using System;
using System.IO;

namespace rename
{
    class Program
    {
        static void Main(string[] args)
        {
            // Fix files, replace text
            DirectoryInfo di = new DirectoryInfo(@"C:\temp\all\");
            FileInfo[] rgFiles = di.GetFiles("*");

            foreach (FileInfo fi in rgFiles)
            {
                string[] alllines = File.ReadAllLines(fi.FullName);

                for (int i = 0; i < alllines.Length; i++)
                {
                    if (alllines[i].StartsWith("00:"))
                    {
                        // Edit: Replace these lines with an empty line
                        alllines[i] = alllines[i].Replace(alllines[i], "");
                    }
                }

                // Rewrite new files in the folder
                File.WriteAllLines(@"C:\temp\new\" + fi.Name, alllines);
            }
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,