C#替换文件中的字符串

23

当替换HTML文件的内容时,String.Replace 似乎无法正常工作。例如,String.Replace</body></html> 替换为 blah blah blah </body></html> html> - 请注意第二个HTML结束标记未被正确关闭,因此在用户在浏览器中呈现页面时会显示出来。

有人知道原因吗?

StreamReader sr = fi.OpenText;
String fileContents = sr.ReadToEnd();
sr.close();
fileContents = fileContents.Replace("<body>", "<body onload='jsFx();' />");
fileContents = fileContents.Replace("</body>","blah blah blah </body>");

StreamWriter sw = new StreamWriter(fi.OpenWrite());
sw.WriteLine(contents);
sw.close();

1
你能提供一个源文件的例子吗?你提交的代码应该按照你描述的那样工作。我不明白为什么会出现额外的 html> 部分... - Nate
1
那个多余的标签有没有可能已经在输入文件中了?另外我注意到代码示例中你有一个自动关闭的 body 标签,是这样吗? - MrEyes
Nate - 感谢您的快速回复和清理。虽然不是实际代码,但足以表达我的意思。 - Joey
2个回答

56

我可能会像这样重写你的代码:

var fileContents = System.IO.File.ReadAllText(@"C:\File.html");

fileContents = fileContents.Replace("<body>", "<body onload='jsFx();' />"); 
fileContents = fileContents.Replace("</body>","blah blah blah </body>"); 

System.IO.File.WriteAllText(@"C:\File.html", fileContents);

我应该指出,这个解决方案适用于大小合理的文件。根据硬件情况,在几十MB以下的任何内容都可以。它会将整个内容加载到内存中。如果你有一个非常大的文件,你可能需要每次流传几百KB,以防止OutOfMemoryException。这使得事情变得更加复杂,因为你还需要检查每个块之间的断点,看看是否分割了搜索字符串。


这个功能的一个很棒的特点是,它是我在任何地方看到的唯一一个完全保留原始文件中换行符的答案。我正在读取一个XAML文件,这种方法意味着在跨越多行的元素内部的换行符保持不变! - Ewan

13

string.Replace 没有问题。

错误在于您正在覆盖文件但并未将其截断... 因此,如果您将编写代码更改为以下内容

sw.WriteLine("Start");

如果你使用了 File.ReadAllTextFile.WriteAllText(从FileInfo中获取路径),那么:

  • 它将完全替换文件,而不是仅仅覆盖
  • 您无需担心正确地关闭读取器/编写器/流(当前未执行此操作 - 如果发生异常,您将使读取器或编写器处于打开状态)

如果您真的想使用FileInfo方法,请使用 FileInfo.Open(FileMode.Create),这会截断文件。


Jon - 感谢您的快速回答和解释。请解释一下为什么我不需要在上面的示例中关闭读取器/写入器/流。- 我意识到我提供的代码很糟糕。它不是从开发中复制的,而只是为了让我的问题得到解答。 - Joey
1
@Joey:只有在没有异常的情况下才关闭它们。无论发生什么情况,您都应该使用“using”语句来处理它们 - 这相当于try/finally。 - Jon Skeet
@Joey 现在有点晚了,但请注意你的“新”的起始<body>标签中多了一个/,终止了xml块。 它不应该有结束斜线:<body onload =“”/>。 - sirthomas

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