1

Currently I have some code to replace strings in a file that looks like this:

File.WriteAllText(filePath, Regex.Replace(File.ReadAllText(filePath),
    "( " + column.Key + " )",
    " " + column.Value + " "
));
File.WriteAllText(filePath, Regex.Replace(File.ReadAllText(filePath),
    "(\\[\"" + column.Key + "\"\\])",
    "[\"" + column.Value + "\"]"
));

However, each replacement opens and closes the file, and it seems that occasionally they run "too fast" and one replacement will not work because the file did not close yet in a previous string replacement. Is there any code I can reuse that solves this issue, perhaps using the FileStream class (so I can open and close once)? Or suggestions on a better way to do this? Just wondering if there is something simpler I can do than having to create byte arrays of the strings I want to replace and writing code to read, write, and seek through bytes manually. Thanks.

Matthew Steven Monkan
  • 8,170
  • 4
  • 53
  • 71
  • 1
    Are those lines running back to back just like you have in the code? File IO is very expensive and should be read into a string once, do all replacements, then write to file reducing File IO from 4 read/writes down to 2. – Joe Apr 12 '11 at 16:31
  • 1
    Also your two regexes differ only slightly, so you could combine them into a single one fairly easily. – Michael Low Apr 12 '11 at 16:48
  • They are running back to back. I was looking to open and close the file once; for some reason I just wasn't "seeing" that all I needed to do was create a string variable to perform the multiple Regex's on. I feel a bit silly now that I had to ask the question, but at least it reminded me that it helps to first separate the multiple method calls when they are packed together in the same line and make sure I understand exactly what's going on. I just kept finding code that looked like above when I was searching the web. :) – Matthew Steven Monkan Apr 12 '11 at 16:55
  • @mikel How can the two be combined into one regex? – Matthew Steven Monkan Apr 12 '11 at 19:01
  • http://stackoverflow.com/questions/1915632/open-a-file-and-replace-strings-in-c-sharp – Thomas Jul 11 '12 at 18:39

6 Answers6

4

A better practice would be to read the contents of the file once, storing it into a local variable. Then performing any changes you need (in your case, two regular expressions), and then writing that output to the file. File IO is one of the most expensive operations a computer can perform, and in-memory computation is much cheaper. Hit the disk as little as possible, as long as you can avoid it.

Thebigcheeze
  • 3,408
  • 2
  • 22
  • 18
3

Well, I'd use:

 string text = File.ReadAllText(filePath);

 text = Regex.Replace(...);
 text = Regex.Replace(...);
 ...
 File.WriteAllText(filePath, text);

I'm still surprised to hear that the original code didn't work though. It wasn't pleasant in terms of multiple writes and reads, but I'd have expected it to work.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
2
string contents = File.ReadAllText(filePath);
contents = Regex.Replace(contents,
    "( " + column.Key + " )",
    " " + column.Value + " ");
contents = Regex.Replace(contents,
    "(\\[\"" + column.Key + "\"\\])",
    "[\"" + column.Value + "\"]");
File.WriteAllText(filePath, contents);
Shaun Bowe
  • 9,840
  • 11
  • 50
  • 71
1

Sounds like you should be doing your all your string replacements on a string residing in memory, then write your final resulting string to disk.

iZ.
  • 4,951
  • 5
  • 23
  • 16
1
var fileContents = File.ReadAllText(filePath);
fileContents = Regex.Replace(fileContents,
    "( " + column.Key + " )",
    " " + column.Value + " "
);
fileContents = Regex.Replace(fileContents ,
    "(\\[\"" + column.Key + "\"\\])",
    "[\"" + column.Value + "\"]"
);
File.WriteAllText(filePath, fileContents);
Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
1

Well, the simlest method would be to ReadAllText, do your replacements and then WriteAllText.

var text = File.ReadAllText(filePath);
text = Regex.Replace(text,"( " + column.Key + " )"," " + column.Value + " ");
text = Regex.Replace(text,"(\\[\"" + column.Key + "\"\\])","[\"" + column.Value + "\"]");
File.WriteAllText(text,filePath);
Jamiec
  • 133,658
  • 13
  • 134
  • 193