c# replace string within file

2019-03-22 18:38发布

问题:

String.Replace doesn't seem to work properly when replacing a portion of an HTML file's content. For example, String.Replace replaces </body></html> with blah blah blah </body></html> html> - notice the second HTML closing tag is not properly closed and therefore shows up when the page is rendered in the browser by the user.

Anyone know why it's not working as intended?

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:

I might rewrite your bit of code like this:

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

I should note that this solution is fine for files of reasonable size. Depending on hardware, any thing under a few tens of MB. It loads the entire contents into memory. If you have a really large file you may need to stream it through a few hundred KB at a time to prevent an OutOfMemoryException. That makes things a bit more complicated, since you'd need to also check the break between each chunk to see if split your search string.



回答2:

There's nothing wrong with string.Replace here.

What is wrong is that you're overwriting the file but not truncating it... so if you changed your writing code to just

sw.WriteLine("Start");

you'd see "Start" and then the rest of the file.

I would recommend that you use File.ReadAllText and File.WriteAllText instead (take the path from the FileInfo). That way:

  • It will completely replace the file, instead of just overwriting
  • You don't need to worry about closing the reader/writer/stream properly (which you're not doing now - if an exception occurs, you're leaving the reader or writer open)

If you really want to use the FileInfo methods, use FileInfo.Open(FileMode.Create) which will truncate the file.