Существует, чтение и запись всего за один шаг

#c# #file #file-handling

#c# #файл #обработка файлов

Вопрос:

Я пытаюсь выяснить, существует ли файл, если он существует, проверьте, существует ли уже стиль css, если нет, запишите их в конец файла…

Я уже делаю все это, но в 3 шага:

Существует ли файл?

 FileInfo fi= new FileInfo(Path.Combine(rootPath, "DefaultStyles.css");
  

Если это так, я использую TextReader для получения содержимого

 using (TextReader tr = new StreamReader(file))
{
    r = tr.ReadToEnd().Contains(".onebyonecard");
    tr.Close();
}
  

Затем я записываю в него, если стиль не был найден

 using (TextWriter tw = new StreamWriter(file))
{
    tw.Write(cssStyle);
    tw.Close();
}
  

Есть ли способ сделать это одним простым открытием / закрытием, вместо этого нужно открывать файл снова и снова?

Ответ №1:

Ну, вы можете открыть один поток для чтения и записи, но, учитывая, что вы читаете весь файл, я бы лично просто открыл его дважды. Обратите внимание, что ваш текущий код будет перезаписывать файл, а не добавлять к нему.

Я бы лично использовал статические методы в File классе:

 // Elide this into the "if" condition if you want. I've separated it out here,
// but obviously it makes no difference.
bool present = File.Exists(path) amp;amp;
               File.ReadAllText(path).Contains(".onebyonecard);
if (!present)
{
    File.AppendAllText(path, cssStyle);
}
  

Это проще, чем иметь поток чтения / записи и создавать над ним как a TextReader , так и a TextWriter .

Пара замечаний:

  • При разделении доступа к файлам существует небольшой риск возникновения состояния гонки. Мы могли бы открыть файл, прочитать содержимое, затем его можно обновить, пока мы решаем, что делать дальше. Аналогично, файл может существовать, когда мы выполняем проверку, но затем быть удален до его чтения. В большинстве приложений этот риск настолько мал, что не имеет значения — только вы можете сказать наверняка.
  • Приведенный выше код все равно может выдавать исключение, если файл существует, но не может быть прочитан / записан соответствующим пользователем или используется другим процессом. Применяется обычный стиль обработки исключений — решите, в какой степени, по вашему мнению, вы действительно можете оправиться от таких ситуаций, и действуйте соответствующим образом.

Ответ №2:

Ну, поскольку вы используете ReadToEnd() , вы могли бы также использовать:

 if (!File.Exists(file) || !File.ReadAllText(file).Contains(".onebyonecard"))
    File.AppendAllText(file, cssStyle);
  

но это все равно открывает его дважды. Существуют API, которые позволяют открывать его только один раз, но это двоичные API ( Stream etc), которые будут работать, но, вероятно, излишни для вашего сценария.

Комментарии:

1. Я не думаю, что вы имеете в виду AppendText 🙂

2. @Джон черт возьми; Я знал , что компиляторы существуют не просто так

Ответ №3:

 try
{
TextReader tr = new StreamReader(file);
r = tr.ReadToEnd().Contains(".onebyonecard");
tr.Close();
tr.Dispose ();
}
catch { //File is not exists or is used by another application
}
  

Комментарии:

1. Вы должны использовать using инструкции вместо закрытия вручную. Вы также не ответили на вопрос — в настоящее время вы просто показываете худшую версию того, что уже делает OP.