У меня есть приложение, которое работает с форматами файлов XML.Приложение может вносить изменения в эти файлы XML, но оно также использует System.IO.FileSystemWatcher, чтобы увидеть, изменились ли файлы XML за пределами программы во время ее работы.Если файлы изменились, то приложение перезагружает файлы XML.
Конечно, если приложение сохраняет файл XML, это заставляет Windows обнаруживать, что файл изменился, что запускает события FileSystemWatcher,Я не хочу, чтобы файл перезагружал файлы XML из-за изменений, которые он инициировал, поэтому всякий раз, когда он сохраняет файл XML, он хранит счетчик количества раз, которое следует игнорировать при изменении конкретного файла.Сохранение файла XML в приложении увеличивает количество.Реакция на изменение в файле уменьшает счетчик, если он не равен нулю, или обрабатывает изменение, если счет уже равен 0.
Проблема, с которой я сталкиваюсь, заключается в том, что при сохранении файла XML я делаю это следующим образом:
Stream fileStream = null;
if(System.IO.File.Exists(fileToSave)
{
fileStream = System.IO.File.Open(fileName, FileMode.OpenOrCreate | FileMode.Truncate);
}
else
{
fs = System.IO.File.Open(fileName, FileMode.OpenOrCreate);
}
...
Затем я сериализую свой объект XML в поток, используя XmlWriter, затем закрываю поток.Все работает нормально, за исключением того, что мои события в FileSystemWatcher будут вызваны дважды.Я потратил некоторое время на отладку и обнаружил, что вызов System.IO.File.Open с параметром Truncate фактически изменяет файл на диске.Я достиг точки останова сразу после вызова и обнаружил, что файл XML находится на диске размером 0 байт.Поэтому, похоже, что этот подход дважды попадает на диск, в результате чего мои события FileSystemWatcher возникают дважды.
Как решить эту проблему?
В качестве обходного пути я обнаружил, что могуудалите файл, если он существует, затем выполните простой File.Open без опции Truncate, а в моем случае это решает ... по крайней мере, пока.Я предполагаю, что это будет ударом по событию Delete в FileSystemWatcher.Технически я не хочу удалять файл, и если бы мне пришлось добавить определенную логику, когда файл будет удален позднее, этот код, вероятно, вызвал бы его неправильную работу.
Любые другие способыизменить существующий файл, не вызывая 2 события FileSystemWatcher?
обновление 1
Прошло много лет с тех пор, как я задал этот вопрос и файлСистема часов стала центральной частью приложения, с которым я работаю и поддерживаю с тех пор, как я задавала этот вопрос более 5 лет назад.
К сожалению, с тех пор я все еще не нашла лучшего решения дляSerliaizing XML на диск, не вызывая 2 файла наблюдения изменений.
Для будущих читателей вот код, который я использую:
if (System.IO.File.Exists(fileName))
{
System.IO.File.Delete(fileName);
}
using( var fs = System.IO.File.Open(fileName, FileMode.OpenOrCreate))
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
using(var writer = XmlWriter.Create(fs, settings))
{
// for info on this, see
// /1080329/xmlserializer-dayschii-filenotfoundexception-u-konstruktora
XmlSerializer serializer = XmlSerializer.FromTypes(new[] { type })[0];
serializer.Serialize(writer, objectToSerialize);
}
}