Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 12.02.2014, 13:14   #1
makc9I
Пользователь
 
Регистрация: 25.10.2012
Сообщений: 11
По умолчанию Отслеживание директории на наличие файлов

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

Я реализовал это так:

Код:
procedure TForm1.sendFilesClick(Sender: TObject);
var
  sr : tSearchRec;
  i : integer;

begin

  while FindFirst(BIS_IN_PATH + '*.txt', faAnyFile - faDirectory - faVolumeID, sr) = 0 do
  begin
    i := 0;
    repeat
      i := i + 1;
    until FindNext(sr) <> 0;
    FindClose(sr);
    label_bis_send.Caption := 'Осталось обработать: ' + inttostr(i);
    sleep(5000); //5 секундная задержка до следующей проверки
  end;

end;
В принципе, данный код даже работает, но есть одно НО, форма намертво повисает до тех пор, пока каталог не опустеет и label_bis_send.Caption не обновляется вообще.

Да и в целом я не уверен, что данный код решает задачу оптимальным способом.

Вопроса два:
1) Как решить проблему с отображение количества файлов на форме
2) Можно ли решить задачу более оптимальным способом?
makc9I вне форума Ответить с цитированием
Старый 12.02.2014, 13:27   #2
ZuBy
Участник клуба
 
Аватар для ZuBy
 
Регистрация: 29.09.2008
Сообщений: 1,234
По умолчанию

вот
и вот
мониторинг папок быстро ищется в гугле!
ZuBy вне форума Ответить с цитированием
Старый 12.02.2014, 13:58   #3
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

в упрощеном виде повесить сие на таймер и while со sleep убрать
Не стесняемся, плюсуем!
Slym вне форума Ответить с цитированием
Старый 12.02.2014, 14:40   #4
makc9I
Пользователь
 
Регистрация: 25.10.2012
Сообщений: 11
По умолчанию

ZuBy,
Пока так и не вкурил, как это делается.
Вот читаю листинг программы по вашей ссылке номер 2.
Нашел такую строку:
Код:
 Application.MessageBox('Отвянь, гнида!', 'Помощи хочешь?', MB_OK+MB_ICONINFORMATION);
Прям читать дальше расхотелось сие творчество.

Как я понимаю, чтобы мой код заработал на отображение количества файлов(обновление label), необходимо все это дело в отдельный поток завернуть?
Пойду гуглить о потоках.

Slym, сейчас попробую ваш вариант
makc9I вне форума Ответить с цитированием
Старый 12.02.2014, 14:42   #5
ZuBy
Участник клуба
 
Аватар для ZuBy
 
Регистрация: 29.09.2008
Сообщений: 1,234
По умолчанию

я не особо вчитывался, это просто выборка из гугла.
я бы посоветовал 1 ссылку посмотреть, там как раз с потоком сделано
ZuBy вне форума Ответить с цитированием
Старый 12.02.2014, 14:55   #6
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

во-первых, делать подобные циклы - моветон! Хоть в потоке, хоть не в потоке!
Но, если уж Вы пишите индусский код, так, по крайней мере, отдавайте в цикле циклы операционной системе, вставьте внутрь цикла
строчку :
Код:
   Application.ProcessMessages;
во-вторых, чтобы не делать задержку на пять секунд, достаточно было повесить данный код просто на событие таймера (кстати, Application.ProcessMessages; всё равно нужно и в этом случае, чтобы форма "не зависала"!

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


p.s. извините, по ссылкам не ходил. Подозреваю, что там как раз то, о чём я и написал в своё сообщении
Serge_Bliznykov вне форума Ответить с цитированием
Старый 12.02.2014, 15:04   #7
makc9I
Пользователь
 
Регистрация: 25.10.2012
Сообщений: 11
По умолчанию

Все получилось, спасибо Slym
Рабочий код такой:

Код:
//Обработчик клика на кнопку
procedure TForm1.sendFilesClick(Sender: TObject);
begin
  label_bis_send.Caption := 'Обработка...';
  timer1.Enabled := true;
end;

//обработчик таймера
procedure TForm1.Timer1Timer(Sender: TObject);
var
  sr : tSearchRec;
  i : integer;
begin
    Application.ProcessMessages;
    if FindFirst(BIS_IN_PATH + '*.txt', faAnyFile - faDirectory - faVolumeID, sr) = 0 then
    begin
      i := 0;
      repeat
        i := i + 1;
      until FindNext(sr) <> 0;
      FindClose(sr);
      label_bis_send.Caption := 'Осталось обработать: ' + inttostr(i);
      //Form1.Refresh;
      end
    else begin
      Timer1.Enabled:=False;
      label_bis_send.Caption := 'Все файлы выгружены';
    end;


end;

Последний раз редактировалось makc9I; 12.02.2014 в 15:07.
makc9I вне форума Ответить с цитированием
Старый 12.02.2014, 15:11   #8
makc9I
Пользователь
 
Регистрация: 25.10.2012
Сообщений: 11
По умолчанию

Serge_Bliznykov, я догадываюсь, что задачу можно решить гораздо изящней и красивей, написал первое, что пришло в голову. Мой опыт разработки на делфи сводится к написанию пятерки программ, обрабатывающих всякие данные из DBF и прочего и формирующие ответы. А мои знания в этой среде сводятся к компьютерной школе, законченной 8 лет назад, школьным знаниям, базированным на Паскале, ну и с десяток программ, написанных в универе.
Я программист по образованию, но не по профессии, т.е. опыта у меня около нуля. Именно поэтому мой код, вероятнее всего, отдает душком, и действительно его можно назвать индусским.
makc9I вне форума Ответить с цитированием
Старый 12.02.2014, 19:02   #9
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

Application.ProcessMessages; в таймере не нужен
Не стесняемся, плюсуем!
Slym вне форума Ответить с цитированием
Старый 12.02.2014, 22:36   #10
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Сообщение от Slym Посмотреть сообщение
Application.ProcessMessages; в таймере не нужен
Вы не правы!


если на таймере будет висеть код типа:
Цитата:
Код:
    if FindFirst(BIS_IN_PATH + '*.txt', faAnyFile - faDirectory - faVolumeID, sr) = 0 then
    begin
      i := 0;
      repeat
        i := i + 1;
      until FindNext(sr) <> 0;
      FindClose(sr);
то, при наличии в каталоге большого количества подходящих файлов форма будет так же морозиться, как и при обычной обработке!

Таймер позволит избавиться от цикла со Sleep, тут, безусловно - ГУД!
Но между repeat .. until тоже ProcessMessages будет полезен!
Serge_Bliznykov вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
c# и ms sync framework - отслеживание заменяемых файлов до синхронизации Vygor C# (си шарп) 1 07.06.2012 18:03
.NET Алгоритм проверки каждые n мсек наличие файла в текущей директории omigos99 Общие вопросы .NET 2 10.12.2011 19:37
Чтение файлов из директории WarAngel.alk PHP 2 22.10.2011 18:45
Программа получения списка файлов директории и изменения атрибутов файлов roma86 Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 7 09.06.2009 09:08
Отслеживание создания файлов 5naip Общие вопросы Delphi 4 18.07.2008 14:53