Как победить в гонке «открыть после закрытия файла» - PullRequest
0 голосов
/ 08 октября 2018

Существует программа, которая выполняет общеизвестное атомарное обновление файла:

file = open("foo.txt.tmp")
... write
file.close()
rename("foo.txt.tmp", "foo.txt")

Некоторые клиенты сообщают, что это не удалось, поскольку foo.txt.tmp занято.Я подозреваю, что это может быть из-за антивируса или других программ, которые открывают файл для его сканирования.

Я хочу проверить это дело.Для этой цели я написал программу, которая использует FileSystemWatcher , которая обнаруживает файл, создаваемый или изменяемый, а затем сохраняет его открытым в течение нескольких миллисекунд.В C # это примерно так:

watcher = new FileSystemWatcher();
...
// there is also .Created, but it comes earlier anyway
watcher.Changed += OnChanged;
...

...
static void OnChanged(object sender, FileSystemEventArgs e)
{
    Task.Run(() =>
    {
        using(var h = File.Open(e.FullPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
        {
            Thread.Sleep(500); // some sleep, in real code I can vary it but should not matter
        }
    })
}

В основном это работает, но иногда происходит сбой открытия с исключением: «Процесс не может получить доступ к файлу« ... », потому что он используется другим процессом»,или даже "Не удалось найти файл '...'".Таким образом, файл уже обрабатывается основной программой.Иногда я проигрываю эту гонку довольно много раз, поэтому некоторые случаи остаются непроверенными.

Вопрос в том, как я могу быть более уверен, что моя тестовая реализация откроет файл раньше других.Это должно быть возможно сделать, не так ли?Иначе как бы это сделали антивирусы?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...