[英]C# Search file for a string and get the string's line number
我整天都在这里,我正在努力做到这一点,我搜索得越来越远,虽然有类似的问题,但没有答案。
我正在尝试做的事情:我正在尝试搜索文件中的多个字符串并接收行号,以便当用户希望更改我的应用程序中的所述字符串时,我的应用程序知道要用其字符串替换哪些行。
到目前为止我尝试过的:我已经尝试了以下代码,我的尝试是读取文件然后接收行号,但它似乎根本不起作用。
var lines = File.ReadAllLines(filepath);
foreach (var match in lines // File.ReadLines(filePath)
.Select((text, index) => new { text, lineNumber = index + 1 })
.Where(x => x.text.Contains("motd=")))
{
lines[match.lineNumber] = "motd=" + textBox1.Text;
File.WriteAllLines(filepath, lines);
}
}
我希望上面的代码可以在文件中找到字符串“motd =”,获取行号并尝试用用户输入的内容重新编写它。
但是,我收到此错误:“ Index was outside the bounds of the array
”。
我认为for
循环在这里更有意义
var lines = File.ReadAllLines(filepath);
for (int i = 0; i < lines.Length; i++)
{
if(lines[i].Contains("motd="))
{
lines[i] = "motd=" + textBox1.Text;
}
}
File.WriteAllLines(filepath, lines);
您的代码有两个问题是您在循环中写出文件并将索引增加1,然后指向数组中的错误行,如果最后一行包含,则会导致异常您要搜索的文字。
应该注意的是,如果你正在处理一个非常大的文件,这可能是一个内存耗尽。 在这种情况下,我会一次读取一行并将它们写入临时文件,然后删除原始文件并在结尾重命名temp。
var tempFile = Path.GetTempFileName();
using (var file = File.OpenWrite(tempFile))
using (var writer = new StreamWriter(file))
{
foreach (var line in File.ReadLines(filepath))
{
if (line.Contains("motd="))
{
writer.WriteLine("motd=" + textBox1.Text);
}
else
{
writer.WriteLine(line);
}
}
}
File.Delete(filepath);
File.Move(tempFile, filepath);
这将更快,并使用更少的内存,并使用非常大的文件,但您需要写入一个新文件:
File.WriteAllLines(filepath2,
File
.ReadLines(filepath)
.Select(x=>x.Contains("motd=")?"motd="+TextBox1.Text:x));
它使用ReadLines,它尽可能读取每一行而不是读取整个文件,并在一步中将其分成行。 因此,它会在文件系统可以读取,处理行,然后写入结果的同时快速处理它。
完整的替换将如下所示:
var filepath2= Path.GetTempFileName();
File.WriteAllLines(filepath2,
File
.ReadLines(filepath)
.Select(x=>x.Contains("motd=")?"motd="+TextBox1.Text:x));
File.Delete(filepath);
File.Move(filepath2, filepath);
要做多个值:
var filepath2= Path.GetTempFileName();
File.WriteAllLines(filepath2,
File
.ReadLines(filepath)
.Select(x=> {
if (x.Contains("motd=")) return "motd="+TextBox1.Text;
if (x.Contains("author=")) return "author="+TextBox2.Text;
return x;
}));
File.Delete(filepath);
File.Move(filepath2, filepath);
或者将替换逻辑移动到它自己的函数:
string ReplaceTokens(string src)
{
if (src.Contains("motd=")) return "motd="+TextBox1.Text;
if (src.Contains("author=")) return "author="+TextBox2.Text;
return src;
}
var filepath2= Path.GetTempFileName();
File.WriteAllLines(filepath2,
File
.ReadLines(filepath)
.Select(ReplaceTokens));
File.Delete(filepath);
File.Move(filepath2, filepath);
你在每一次迭代上编写文件是没有意义的,而做一个select / where / index事情只是很奇怪。
既然你做了Where
,你必须遍历每一行,所以为什么不救的麻烦,只是遍历所有明确?
var lines = File.ReadAllLines(filepath);
for(int i = 0; i < lines.Length; i++)
{
if(lines[i].Contains("motd="))
{
lines[i] = "motd=" + textBox1.Text;
}
}
File.WriteAllLines(filepath, lines);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.