C #, Windows 7: как я могу надежно проверить, записывается ли процесс в файл? - PullRequest
1 голос
/ 06 марта 2012

У меня есть утилита C #, которая должна выполнить некоторые действия, как только конкретный файл будет выпущен другим процессом, то есть этот процесс прекратит запись в файл.Я использую приведенный ниже код, но он работает некорректно в системе Windows 7.

private static bool FileWritten(string filename)
    {
        try
        {
            using (FileStream inputStream = File.Open(filename, FileMode.Open,
                        FileAccess.Read,
                        FileShare.None))
            {
                return true;
            }
        }
        catch (IOException e)
        {
            return false;
        }
    }

Иногда он возвращает false, даже если кажется, что файл уже выпущен.Я вызываю FileWritten () в цикле while (true), который продолжает проверять вызов FileWritten () до тех пор, пока он возвращает false, а затем завершается через некоторое максимальное время.Отладить это сложно, так как кажется, что он отлично работает в отладчике (то есть он возвращает true, как только файл на самом деле выпущен), но затем не работает, когда я запускаю свой код напрямую.Кроме того, даже добавление отладочных отпечатков, похоже, влияет на его поведение.

Есть ли более надежный способ проверить, был ли файл записан и выпущен, который будет работать в Win 7 и, предпочтительно, также в Win XP?

Ответы [ 2 ]

1 голос
/ 06 марта 2012

Идеального решения этой проблемы не существует.

Даже если ваш код работал в Windows 7 нормально, условия гонки все равно будут.

Представьте себе, FileWritten возвращает false в определенный момент времени.Ваш код предполагает, что файл больше не заблокирован и продолжает выполнение ... но файл может быть снова заблокирован в следующую миллисекунду, и в следующий раз, когда вы попытаетесь получить доступ к файлу, он выдаст исключение ...

Разве вы не можете просто попытаться получить доступ к вашему файлу и поймать исключение, если вы не можете получить к нему доступ?Затем вы можете подождать некоторое время и повторить попытку.Было бы чище IMO, чем функция, которая пытается вернуть логическое значение, указывающее, используется ли файл процессом или нет.

0 голосов
/ 06 марта 2012

Вы можете использовать FileSystemWatcher для прослушивания событий в файле. Некоторые параметры позволят вам увидеть, был ли файл изменен. Вы можете спать в течение определенного времени, используя эффект попкорна (сброс таймера) всякий раз, когда вы получаете уведомление об изменении файла. Затем выполните свой код (но на самом деле сделайте так, чтобы он выполнял свою работу по пути True, пока у вас есть блокировка). Если файл все еще заблокирован, вы получите ложь, поспите еще немного в ожидании событий.

Кроме того, что другой процесс переименовывает / копирует исходный файл в новое место после его завершения, не существует универсального API, который обеспечит вам блокировку файла сразу после того, как другой процесс удалит его. (Что я знаю).

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