M Y D E L P H I 7 . R U Самоучитель программирования  
 
  • Главная
  •  

     

    Оповещение об изменении в файловой системе

    Этот вид объекта ожидания очень интересен и незаслуженно мало известен. Мы рассмотрели практически все варианты того, как один поток может подать сигнал другому. А как получить сигнал от операционной системы? Ну, например, о том, что в файловой системе произошли какие-то изменения? Такой вид оповещения позаимствован из ОС UNIX и доступен программистам, работающим с Win32. Для организации мониторинга файловой системы нужно использовать

    Три функции — FindFirstChangeNotification, FindNextChangeNotification и FinddoseChangeNotification. Первая из них возвращает дескриптор объекта файлового оповещения, который можно передать в функцию ожидания. Объект активизируется тогда, когда в заданной папке произошли те или иные изменения (создание или уничтожение файла или папки, изменение прав доступа и т. д.). Вторая — готовит объект к реакции на следующее изменение. Наконец, с помощью третьей функции следует закрыть ставший ненужным объект.

    Так может выглядеть код метода Execute потока, созданного для мониторинга файловой системы:

    var DirName : string;

    ...

    procedure TSimpleThread.Execute; 

    var r: Cardinal;

    fn : THandle; 

    begin

    fn := FindFirstChangeNotification(pChar(DirName), True,

    FILEJTOTIFY_CHANGE_FILE_NAME);

    repeat

    r := WaitForSingleObject(fn,2000);

    if r = WAIT_OBOECT_0 then

    Synchronize(Forml.UpdateList);

    if not FindNextChangeNotification(fn) then

     break;

     until Terminated; 

    FindCloseChangeNotification(fn);

      end;

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

    procedure TForml.ButtonlClick(Sender: TObject);

     var dir : string; begin

    if SelectDirectory(dir,[],0) 

    then begin

    Editl.Text := dir; DirName := dir;

     end;

      end;

    procedure TForml.UpdateList;

     var SearchRec: TSearchRec;

     begin

    ListBoxl.Clear;

    FindFirst(Editl.Text+'\*.*', faAnyFile, SearchRec); repeat ListBoxl.Items.Add(SearchRec.Name);

    until FindNext(SearchRec) <> 0;

    FindClose(SearchRec);

    end;

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