![]() |
|
#1
|
|||
|
|||
![]() Такая вот ситуация сложилась.
Задача: Небольшая програмка которая бы исполняла роль журнала для файлов. Тоисть мониторила указаную папку и подпапки на наличие файлов удовлетворяющим условие. Должен быть фильтр по маске файла. Например в папке и подпапках есть xml,txt... файли. В програмку помещаеться поле выбора: 1.форматы файлов - заранее прописываються интересующие формати xml,txt например. 2.в имени файла с 5 по 10 символ присутсвует например название склада - нужен фильтр по названию склада. 3.последние 4 символа имени файла - дата документа - нужен фильтр по этой дате. Найденые файли должны отображаться в таблице с возможностью по правому клику на файле выдать контекстное меню с возможностью печати\открытия в блокноте например. Вот такая задачка. Может кто-нить поможет начать ее реализацию, может встречал кто исходники с подобным. Заранее благодарен всем! |
#2
|
|||
|
|||
![]() Я такое писал, создавал поток который сканит выбранную папку на наличие файлов по заранее известной маске, в зависимости от файла выполняет действия.
модуль потока Код:
unit ScanDir; interface uses Classes, Windows, SysUtils; type FParam = record ID: integer; Str: string; // путь к директории с файлами Name: string; // имя потока FName: string; // маска файла end; TScanDir = class(TThread) public constructor Create(Param: FParam); private protected P: FParam; procedure Execute; override; end; implementation uses main; // модуль с формой procedure TScanDir.Execute; var r: Cardinal; fn: THandle; SRec: TSearchRec; begin fn := FindFirstChangeNotification(pChar(P.str), True, FILE_NOTIFY_CHANGE_FILE_NAME); repeat r := WaitForSingleObject(fn, 1000); if r = WAIT_OBJECT_0 then begin if FindFirst(P.Str + '\' + P.AName, faAnyFile, SRec) = 0 then repeat GlobalThreadID := p.ID; // глобальные переменные GlobalThreadName := p.Name; // чтобы в статистике знать GlobalThreadDir := p.Str; // какой поток сработал GlobalThreadFile := SRec.Name; Synchronize(Form1.UpdateMemo); Synchronize(form1.ExtractFile); until FindNext(SRec) <> 0; FindClose(SRec); end; if not FindNextChangeNotification(fn) then break; until Terminated; FindCloseChangeNotification(fn); end; constructor TScanDir.Create(Param: FParam); begin inherited Create(true); P := Param; end; end. ну и соответственно запускаешь потоки из основной программы Код:
... var ThreadScanDir: TScanDir; .... ThreadScanDir := TScanDir.Create(Param); ThreadScanDir.FreeOnTerminate := true; ThreadScanDir.Priority := tplower; ThreadScanDir.Resume; |
#3
|
|||
|
|||
![]() Ну, здесь такое сложное решение даже не нужно. Достаточно просто периодически запускать скан папки с подпапками. Сложнее всего будет с фильтрацией. Если позиции по 2 и 3 пунктам точно фиксированные, то и тут все несложно. Тебе нужны функции FindFirst/FindNext/FindClose и MatchesMask.
Алгоритм примерно такий. В памяти делжим список найденных файлов. Перед поиском его очищаем. Начинаем поиск с корня указанной папки. Если найденный объект есть папка - идем внутрь и рекурсивно вызывем ту же процку. Если файл то: 1. проверяем расширение по маске 2. проверяем номер по позициям в имени файла 3. проверяем дату Если все проверки прошли, то добавляем файл в список. Если нет, то не добавляем. шаблон: Код:
var FoundFiles : TStringList; function CheckFile(AFileName : String; AExt : Array Of String; Awarehouse : String; ADate : String) : Boolean; begin Result := False; // Здесь проверяем на соотв. условиям. Лень писать. // Если все проверки прошли, то Result := True; end; procedure DoFindFiles(APath : String; AExt : Array Of String; Awarehouse : String; ADate : String); var F : TSearchRec; iFound : Integer; begin iFound := FindFirst(APath + '*.*',faAnyFile,F); While iFound = 0 Do Begin If (F.Attr and faDirectory) <> 0 Then DoFindFiles(APath + F.Name + '\',AExt,AWarehouse,ADate) Else If CheckFile(F.Name,AExt,AWarehouse,ADate) Then FoundFiles.Add(APath + F.Name); iFound := FindNext(F); End; FindClose(F); end; proedure FindFiles(APath : String; AExt : Array Of String; Awarehouse : String; ADate : String); begin FoundFiles.Clear; DoFindFiles(APath,AExt,AWarehouse,ADate); end; |