Иллюстрированный самоучитель по Delphi 7 для профессионалов

Поток. Консольный ввод. Оповещение об изменении в файловой системе.

Поток может ожидать другой поток точно так же, как и другой процесс. Ожидание можно организовать с помощью функций API (как в только что рассмотренном примере), но удобнее это сделать при помощи метода TThread.WaitFor.

Консольный ввод

Консольный ввод (console input) годится для потоков, которые должны ожидать отклика на нажатие пользователем клавиши на клавиатуре. Этот тип ожидания может быть использован в программе дуплексной связи (chat). Один поток при этом будет ожидать получения символов; второй – отслеживать ввод пользователя и затем отсылать набранный текст ожидающему приложению.

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

Этот вид объекта ожидания очень интересен и незаслуженно мало известен. Мы рассмотрели практически все варианты того, как один поток может подать сигнал другому. А как получить сигнал от операционной системы? Ну, например, о том, что в файловой системе произошли какие-то изменения? Такой вид оповещения позаимствован из ОС 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;

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

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.