进行以下操作:
我想在c#中实现上述目标,这是我的代码:
using (StreamReader sr = new StreamReader(@"S:\Personal Folders\A\TESTA.txt"))
{
using (StreamWriter sw = new StreamWriter(@"S:\Personal Folders\A\TESTB.txt"))
{
string line;
while ((line = sr.ReadLine())!= null)
{
if (!line.Contains("before"))
{
sw.WriteLine(line);
}
else if (line.Contains("before"))
{
sw.WriteLine(line.Replace("before", "after"));
}
}
}
}
基本上,上面的代码将生成一个带有所需替换操作的新文件,但正如您所看到的,我正在做的方法是读取原始文件的每一行并写入新文件。这可以实现我的目标,但它可能有系统IO问题,因为它是为每一行读写。另外,我无法首先读取所有行到数组,然后写入,因为文件很大,如果我尝试写入string[]
,则替换all,然后将数组写入文件,将带来内存超时问题。
有什么方法可以找到特定的线条,只需更换这些线条并保留其余部分?或者解决上述问题的最佳方法是什么?感谢
答案 0 :(得分:1)
一般来说,你正在做的是正确的,可能后面有一些重命名来替换原始文件。如果确实要替换原始文件,则应将原始文件重命名为临时名称,将新文件重命名为原始名称,然后保留或删除原始文件。您必须处理与临时名称的冲突以及所有重命名中的错误。
考虑使用五个字符的字符串替换六个字符的字符串 - 如果您回写原始文件,您将如何处理额外的字符?文件作为原始数据字节存储在磁盘上,没有"文本"磁盘上的文件。如果用较长的字符串替换字符串会怎么样 - 然后可能需要移动文件的其余部分以腾出空间来写更长的行。
您可以将磁盘上的文件想象为方框中的方格纸上写的字母。每行的结尾用特殊字符(或字符 - 在Windows中,即CRLF)标记,字符水平填充所有框。如果您试图替换方格纸上的文字,则必须删除并重写大量字母。在新表上书写将是最简单的。
答案 1 :(得分:1)
嗯,你的方法基本上没问题......但是我不会检查该行是否包含单词before
......权衡利弊是不够的:
using (StreamReader sr = new StreamReader(@"S:\Personal Folders\A\TESTA.txt"))
{
using (StreamWriter sw = new StreamWriter(@"S:\Personal Folders\A\TESTB.txt"))
{
String line;
while ((line = sr.ReadLine()) != null)
sw.WriteLine(line.Replace("before", "after"));
}
}
答案 2 :(得分:1)
我不知道您担心的IO问题,但您的代码应该可以正常工作。您可以按如下方式更简洁地编写代码:
using (StreamReader sr = new StreamReader(@"S:\Personal Folders\A\TESTA.txt"))
{
using (StreamWriter sw = new StreamWriter(@"S:\Personal Folders\A\TESTB.txt"))
{
while ((string line = sr.ReadLine())!= null)
{
sw.WriteLine(line.Replace("before", "after"));
}
}
}
这会运行得更快,因为它每行只搜索一次“之前”。默认情况下,StreamWriter会缓冲您的写入,并且每次调用WriteLine时都不会刷新到磁盘,并且文件IO在操作系统中是异步的,因此不要过于担心IO。
答案 3 :(得分:-1)
请尝试以下操作:
else if (line.Contains("before"))
{
sw.WriteLine(line.Replace("before", "after"));
sw.Write(sr.ReadToEnd());
break;
}