Как определить переименование файла из открытого потока - PullRequest
2 голосов
/ 19 мая 2011

Вопрос:

Можно ли определить, когда файл, для которого есть открытый FileStream, был переименован.

Случай:

Я пытаюсь отслеживатьжурналы для нашего приложения я читаю из файлов журналов, так как не хочу вмешиваться в саму регистрацию.

Это прекрасно работает, пока файл не будет свернут.Мое приложение продолжает чтение из переименованного файла, даже не замечая этого.

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

Если бы я мог узнать, какой файл (имя) у меня открытЯ могу сравнить это с _fileName, но я не знаю, как или можно ли это сделать.

Есть ли другие варианты, которые я мог бы изучить?

Код:

это упрощенная версия моего класса мониторинга файлов:

public class MonitorFile
{
    private String _fileName = String.Empty;
    private bool _stopMonitoring = false;

    public MonitorFile(string fileName)
    {
        _fileName = fileName;
    }

    // Simplified method
    public void StartMonitoring()
    {
        using (var reader = new StreamReader(
                    new FileStream(
                        _monitorFileName,
                        FileMode.Open,
                        FileAccess.Read,
                        FileShare.Delete | FileShare.ReadWrite)))
        {
            while (!_stopMonitoring)
            {
                Thread.Sleep(500);

                while ((line = reader.ReadLine()) != null)
                {
                    //...Do stuff with the lines
                }
            }
        }
    }
}

Ответы [ 3 ]

1 голос
/ 19 мая 2011

Существует пример MSDN, показывающий , как вы можете получить имя файла из дескриптора файла (к которому у вас есть доступ через свойство Handle FileStream) с помощью Win32 API, но я сомневаюсь, что этот подход будет работать для файлов на удаленном сетевом ресурсе.

В общем случае вам может не повезти.

1 голос
/ 19 мая 2011

Вы можете извлечь имя каталога из пути к файлу монитора. Затем после вашего цикла readLine: Получить список файлов в каталоге, отсортированный по дате последнего обновления взять первый пункт в списке сравните его с именем файла, из которого вы читаете, и, если они отличаются, обновите ваш читатель

Это работает при условии, что только файлы в каталоге будут файлами журнала, и вы всегда хотите читать из последнего обновленного файла

0 голосов
/ 19 мая 2011

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

Вы можете попробовать System.IO.File.GetCreationTime , хотя могут быть и другие факторы, влияющие например:

Диски в формате NTFS могут кэшировать мета-информацию файла, например время создания файла, в течение короткого периода времени, известного как «туннелирование файлов».В результате может возникнуть необходимость явно установить время создания файла, если вы перезаписываете или заменяете существующий файл.

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