Mega Code Archive

 
Categories / Delphi / Examples
 

How to realize a ChangeFinder

Title: How to realize a ChangeFinder Question: Where or when a modification has changed an existing file or a new one, the ChangeFinder can show the files in a listview by searching the now system date on your drives. The changed files are shown with attributes, size and path names rather than numbers making it easier to see what's going on on your storage system or hard drive. Answer: This should make it easier to determine which files had changed and diminish the chance that a change is causing an undiscovered impact (spyware, caching, integrity etc.). First we need a class: type TChangeFinder = class private nYear, nMonth, nDay: word; dflistView: TListView; protected procedure ShowFiles (Showpath: string; sr: TSearchRec); public constructor prepList_and_Date(alistView: TListView); procedure SearchDirectories(path: string; const fname: string); end; The call from the client needs an instance of a 3 column TListView and the choosen drive letters: procedure TmainForm1.cfinderClick(Sender: TObject); //tshChangefind: TTabSheet, pageindex=5, event= onShow var drive: string[20]; mycf: TChangeFinder; begin screen.cursor:=crHourglass; drive:= dcbHD.Drive; drive:= drive + ':'; mycf:= TChangeFinder.prepList_and_Date(mainForm1.view); mycf.SearchDirectories(drive + '\','*.*'); mycf.Free; screen.cursor:=crDefault; end; The form independent unit itself scans for all files with the system date of today or now so you get a list in a listview for a filechange detection system for Web Servers, protocol machines, loggers, databases or something else useful ;). Implementation of the unit changefinder: ------------------------------------------------------------ constructor TChangeFinder.prepList_and_Date(alistView: TListView); begin inherited Create; dflistView:= alistView; decodedate(date, nYear, nMonth, nDay); with alistView do begin columns[0].Caption:= 'Filename'; columns[1].Caption:= 'Size'; columns[2].Caption:= 'Attr'; end; with alistView.Items do begin BeginUpdate; Clear; EndUpdate; end; end; procedure TChangeFinder.ShowFiles(Showpath: string; sr: TSearchRec); var arcdisp: string[9]; dateRec: TDateTime; lenStr, fname, fext: string; itNewItem: TListItem; AYear, AMonth, ADay: Word; begin if sr.Attr IN [$8..$F, $28..$2F] then begin if Pos('.', sr.Name) 0 then Delete(sr.Name, Pos('.', sr.Name), 1); end; if (Pos('.', sr.Name) 0) AND (Length(sr.Name) 0) then begin fname:= Copy(sr.Name, 1, Pos('.', sr.Name) - 1); fext:= sr.Name; Delete(fext, 1, Pos('.', fext)); end else begin fname:= sr.Name; fext:= ' '; end; arcdisp:= ' '; {$WARN SYMBOL_PLATFORM OFF} if sr.Attr AND faArchive = faArchive then arcdisp[1] := 'A'; if sr.Attr AND faReadOnly = faReadOnly then arcdisp[2] := 'R'; if sr.Attr AND faHidden = faHidden then arcdisp[3] := 'H'; if sr.Attr AND faSysFile = faSysFile then arcdisp[4] := 'S'; {$WARN SYMBOL_PLATFORM ON} //attr. 8..15, 40..47 if NOT (sr.Attr IN [$8..$F, $28..$2F]) then Str(sr.Size, lenStr); if NOT (sr.Attr IN [$8..$F, $28..$2F]) then begin //check the system now date! dateRec:= FileDatetoDateTime(sr.Time); DecodeDate(dateRec, AYear, AMonth, ADay); if (ADay = nDay) AND (AYear = nYear) AND (AMonth = nMonth) then begin if Showpath[Length(Showpath)] = '\' then Delete(Showpath, Length(Showpath), 1); itNewItem:= dflistView.Items.insert(0); itNewItem.Caption:= Showpath + '\' + fname+ '.' + fext; itNewItem.SubItems.Add(lenStr); itNewItem.SubItems.Add(arcdisp); end; end; end; procedure TChangeFinder.SearchDirectories(path: string; const fname: string); var SRecord : TSearchRec; locShowpath: string; begin (* search of files: *) if Length(path) 0 then if path[Length(path)] '\' then path := path + '\'; SRecord.Name := ''; if FindFirst(path + fname, faAnyfile MOD faDirectory, SRecord) = 0 then begin //Showpath:= ' . '; if SRecord.Name '' then begin if Length(path) 3 then locShowpath:= Copy(path, 1, Length(path) - 1) else locShowpath:= path; end; try repeat //attr 0..14, 32..46 if SRecord.Attr IN [$0..$E, $20..$2E] then ShowFiles(locShowpath, SRecord); until FindNext(SRecord) 0; finally FindClose(SRecord); end; end; //search of dir. including hidden dirs! if FindFirst(path + '*.*', faDirectory or faHidden, SRecord) = 0 then begin try repeat if (SRecord.Attr AND faDirectory 0) AND (SRecord.Name[1] '.') then //recursion to get subdirectories SearchDirectories(path + SRecord.Name, fname); until FindNext(SRecord) 0; finally FindClose(SRecord); end; end; end; end.