Как я могу элегантно реализовать несколько замен строк в одном файле?

В настоящее время у меня есть код для замены строк в файле, который выглядит так:

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

Тем не менее, каждая замена открывает и закрывает файл, и кажется, что иногда они работают «слишком быстро», и одна замена не будет работать, потому что файл еще не закрылся в предыдущей замене строки. Есть ли какой-нибудь код, который я могу повторно использовать, который решает эту проблему, возможно, используя класс FileStream (чтобы я мог открывать и закрывать один раз)? Или предложения по лучшему способу сделать это? Просто интересно, есть ли что-то более простое, что я могу сделать, чем создавать байтовые массивы строк, которые я хочу заменить, и писать код для чтения, записи и поиска по байтам вручную. Спасибо.


person Matthew Steven Monkan    schedule 12.04.2011    source источник
comment
Эти строки идут подряд, как в коде? Файловый ввод-вывод очень дорог и должен быть прочитан в строку один раз, выполнить все замены, а затем записать в файл, уменьшая файловый ввод-вывод с 4 операций чтения/записи до 2.   -  person Joe    schedule 12.04.2011
comment
Кроме того, ваши два регулярных выражения отличаются лишь незначительно, поэтому вы можете довольно легко объединить их в одно.   -  person Michael Low    schedule 12.04.2011
comment
Они бегут спиной к спине. Я хотел открыть и закрыть файл один раз; по какой-то причине я просто не видел, что все, что мне нужно было сделать, это создать строковую переменную для выполнения нескольких регулярных выражений. Я чувствую себя немного глупо теперь, когда мне пришлось задать вопрос, но, по крайней мере, это напомнило мне, что это помогает сначала разделить вызовы нескольких методов, когда они упакованы вместе в одну строку, и убедиться, что я точно понимаю, что происходит. Я просто продолжал находить код, похожий на приведенный выше, когда искал в Интернете. :)   -  person Matthew Steven Monkan    schedule 12.04.2011
comment
@mikel Как их можно объединить в одно регулярное выражение?   -  person Matthew Steven Monkan    schedule 12.04.2011
comment
stackoverflow .com/questions/1915632/   -  person Thomas    schedule 11.07.2012


Ответы (4)


Лучшей практикой было бы прочитать содержимое файла один раз, сохранив его в локальной переменной. Затем выполните любые необходимые изменения (в вашем случае два регулярных выражения), а затем запишите этот вывод в файл. Файловый ввод-вывод — одна из самых дорогих операций, которые может выполнять компьютер, а вычисления в памяти намного дешевле. Ударяйте по диску как можно реже, пока вы можете этого избежать.

person Thebigcheeze    schedule 12.04.2011

Ну, я бы использовал:

 string text = File.ReadAllText(filePath);

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

Я все еще удивлен, узнав, что исходный код не работает. Это было неприятно с точки зрения многократной записи и чтения, но я ожидал, что это сработает.

person Jon Skeet    schedule 12.04.2011
comment
Согласен, должно быть что-то еще. В любом случае я не могу думать, что код не будет работать. - person Shaun Bowe; 12.04.2011

Похоже, вы должны выполнять все свои замены строк в строке, находящейся в памяти, а затем записывать окончательную результирующую строку на диск.

person iZ.    schedule 12.04.2011

Что ж, самым простым способом было бы ReadAllText произвести замену, а затем 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);
person Jamiec    schedule 12.04.2011