Существует, чтение и запись всего за один шаг - PullRequest
2 голосов
/ 20 октября 2011

Я пытаюсь выяснить, существует ли файл, если он существует, проверить, существует ли стиль 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();
}

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

Ответы [ 3 ]

3 голосов
/ 20 октября 2011

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

Я бы лично использовал статические методы в классе 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) &&
               File.ReadAllText(path).Contains(".onebyonecard);
if (!present)
{
    File.AppendAllText(path, cssStyle);
}

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

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

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

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

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

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

0 голосов
/ 20 октября 2011
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
}
...