С# заменить строку в файле

String.Replace не работает должным образом при замене части содержимого файла HTML. Например, 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();

person Joey    schedule 02.12.2010    source источник
comment
Можете ли вы привести пример вашего исходного файла? Предоставленный вами код должен работать так, как вы описываете. Я не вижу никакой причины, по которой вы получили бы дополнительный бит `html›`...   -  person Nate    schedule 03.12.2010
comment
Есть ли шанс, что этот посторонний тег уже есть во входном файле? Также я заметил в примере кода, что у вас есть автоматически закрывающийся тег body, верно?   -  person MrEyes    schedule 03.12.2010
comment
Нейт - спасибо за быстрый ответ и очистку. Не настоящий код, но достаточно близко, чтобы понять мою точку зрения.   -  person Joey    schedule 03.12.2010


Ответы (2)


Я мог бы переписать ваш кусок кода следующим образом:

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

Я должен отметить, что это решение подходит для файлов разумного размера. В зависимости от аппаратного обеспечения, любая вещь размером менее нескольких десятков МБ. Он загружает все содержимое в память. Если у вас есть действительно большой файл, вам может потребоваться передать его через несколько сотен КБ за раз, чтобы предотвратить исключение OutOfMemoryException. Это немного усложняет задачу, поскольку вам нужно будет также проверять разрыв между каждым фрагментом, чтобы увидеть, не разделяет ли ваша строка поиска.

person Nate    schedule 02.12.2010
comment
Одной из замечательных особенностей этого является то, что это единственный ответ, который я где-либо видел, который фактически сохраняет символы новой строки точно так же, как они были в исходном файле. Я читаю файл xaml, и этот подход означает, что символы новой строки в элементах, разделенных на несколько строк, сохраняются! - person Ewan; 18.12.2018

Здесь нет ничего плохого в string.Replace.

Что не так неправильно, так это то, что вы перезаписываете файл, но не усекаете его... поэтому, если вы изменили свой код записи на просто

sw.WriteLine("Start");

вы увидите «Пуск», а затем остальную часть файла.

Я бы рекомендовал вам использовать File.ReadAllText и < a href="http://msdn.microsoft.com/en-us/library/system.io.file.writealltext.aspx" rel="noreferrer">File.WriteAllText вместо этого (возьмите путь от FileInfo) . Туда:

  • Он полностью заменит файл, а не просто перезапишет
  • Вам не нужно беспокоиться о правильном закрытии модуля чтения/записи/потока (чего вы сейчас не делаете - если возникает исключение, вы оставляете модуль чтения или записи открытым)

Если вы действительно хотите использовать методы FileInfo, используйте FileInfo.Open(FileMode.Create), который обрежет файл.

person Jon Skeet    schedule 02.12.2010
comment
Джон - Спасибо за быстрый ответ и объяснение. Пожалуйста, объясните, почему мне не нужно закрывать считыватель/запись/поток в приведенном выше примере. - Я понимаю, что код, который я предоставил, грязный. Это не скопировано из разработки, а просто пытается ответить на мой вопрос. - person Joey; 03.12.2010
comment
@Joey: Вы закрываете их, только если нет исключений. Вы должны использовать операторы using, чтобы избавиться от них, что бы ни случилось - это эквивалентно try/finally. - person Jon Skeet; 03.12.2010
comment
@ Джоуи немного опоздал, но обратите внимание, что в ваших новых начальных тегах ‹body› есть дополнительный / в нем, завершающий блок xml. Он должен не иметь закрывающую косую черту: ‹body onload= /› - person sirthomas; 30.11.2013