Link to home
Start Free TrialLog in
Avatar of Vincentg
VincentgFlag for Netherlands

asked on

Scan directories

Hello,

I need some help, what i like to do is this :

Scan 1 or 2 dirs for files and check when they are modified and then remember the 10 last modified files. The 10 filenames have to be put in a var so i can put them in a HTML file with hyperlinks.

Does somebody have some code that can do this?

Thanks a lot.

Vincent
ASKER CERTIFIED SOLUTION
Avatar of Epsylon
Epsylon

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Epsylon
Epsylon

Note that 'GetFiles' also scans all subdirectories recursively.
Avatar of Vincentg

ASKER

Hello Epsylon,

I copy/paste your code but nothing happens, not even a error message. :(
Do i something wrong or is there a 'little mistake' in the code?

Vincent
You must set the onClick event from your Button
Did you link the Button1Click event properly?
Hi bugroger, guess we had the same idea  :o)
By the way, you can remove the line

     Application.ProcessMessages;

from the code. It's not necessary.
Sorry i didn't link the Button1Click event.. :)
It works 100% now..

many many thanks... :)

Vincent
Thank you very much.. !!
Thank you very much.. !!
There is one little problem :(
In the list are also directories, is it possible to delete them and only put files in the list??

Vincent
Hmmm... I didn't receive a notification message for your last comment. I already had the idea I missed some other notifications, but now I am sure: E-E is devolving  :o(


This should prevent directories form being added to the list:

procedure GetFiles(const DirStr : string; filelist: TList);
var
  DirInfo: TSearchRec;
  r : Integer;
  fr: PFile;
begin
  ChDir(DirStr);
  r := FindFirst('*.*', FaAnyfile, DirInfo);
  while r = 0 do
  begin
    if (DirInfo.Name <> '.') and (DirInfo.Name <> '..') then
    begin
      if (DirInfo.Attr and faDirectory) = 0 then
      begin
        New(fr);
        fr.filename := DirStr + '\' + DirInfo.Name;
        fr.filedate := FileDateToDateTime(DirInfo.Time);
        filelist.Add(fr);
      end
      else
        GetFiles(DirStr + '\' + DirInfo.Name, filelist);
    end;
    r := FindNext(DirInfo);
  end;
  FindClose(DirInfo);
end;
Thanks a lot for your help.. :)

Hello Epsylon,

I searched EE for this one but can't find anything.
I would like to scan the subdirs also.. Can you help??
It's no problem to make it a question, you only have to say so..

Thanks again..

Vincent
As far as I can see it does already scan subdirs...
Hi Epsylon,

Not here, if i give c:\ it only checks c:\ and no subdirs..

Avatar of kretzschmar
guessing the recursion want to change the directory to

c:\\anyotherdirname

which is not possible

just use this changes

procedure GetFiles(const DirStr : string; filelist: TList);
var
 DirInfo: TSearchRec;
 r : Integer;
 fr: PFile;
begin
 ChDir(DirStr);
 r := FindFirst('*.*', FaAnyfile, DirInfo);
 while r = 0 do
 begin
   if (DirInfo.Name <> '.') and (DirInfo.Name <> '..') then
   begin
     if (DirInfo.Attr and faDirectory) = 0 then
     begin
       New(fr);
       fr.filename := DirStr + '\' + DirInfo.Name;
       fr.filedate := FileDateToDateTime(DirInfo.Time);
       filelist.Add(fr);
     end
     else
       if DirStr[length(DirStr)] <> '\' then   //here is the change
         GetFiles(DirStr + '\' + DirInfo.Name, filelist)
       else
         GetFiles(DirStr + DirInfo.Name, filelist);
   end;
   r := FindNext(DirInfo);
 end;
 FindClose(DirInfo);
end;

meikl ;-)
Vincent, doesn't it scan subdirs or do you get an error?
I fixed the \ problem and the scan now skips system directories (_Restore, System Volume Information, RECYCLER, etc,) which will interrupt the scan with an access denied error.


procedure GetFiles(DirStr : string; filelist: TList);
var
  DirInfo: TSearchRec;
  r : Integer;
  fr: PFile;
begin
  if DirStr[Length(DirStr)] <> '\' then
    DirStr := DirStr + '\';
  ChDir(DirStr);
  r := FindFirst('*.*', FaAnyfile, DirInfo);
  while r = 0 do
  begin
    if (DirInfo.Name <> '.') and (DirInfo.Name <> '..') then
    begin
      if (DirInfo.Attr and faDirectory) = 0 then
      begin
        New(fr);
        fr.filename := DirStr + DirInfo.Name;
        fr.filedate := FileDateToDateTime(DirInfo.Time);
        filelist.Add(fr);
      end
      else
        if (DirInfo.Attr and faSysFile) = 0 then
          GetFiles(DirStr + DirInfo.Name, filelist);
    end;
    r := FindNext(DirInfo);
  end;
  FindClose(DirInfo);
end;
I now know what the problem is. If i scan for *.html it seems that the subdirs are not scaned. It only find files in the given dir, if i change it to *.* it works 100%.. very strange :(

I now know what the problem is. If i scan for *.html it seems that the subdirs are not scaned. It only find files in the given dir, if i change it to *.* it works 100%.. very strange :(

Ofcource with *.html it wil not find the subdirs :)
Is there a workaround for this??
Ofcource with *.html it wil not find the subdirs :)
Is there a workaround for this??
i use this sceleton

procedure FindFile(PathFileName : string; IncludeSubDirs : Boolean);

     var
       srec : TSearchRec;
       FHandle : integer;
       Path, FileName : String;
     begin
       Path := ExtractFilePath(PathFileName);
       FileName := ExtractFileName(PathFileName);
       // CurrentDirectory
       if findfirst(PathFileName,faanyfile,srec) = 0 then
       begin
         repeat
           If Not(srec.attr and fadirectory > 0) then
           begin

                  // FileFound do something with it

           end;
         Until findnext(srec) <> 0;
       end;
       FindClose(SRec);
       { SubDirectories }
       If IncludeSubDirs then
       begin
         if FindFirst(Path+'*.*',FaAnyFile,Srec) = 0 then
         begin
           repeat
             // StartRecursion
             if not(Srec.Name[1] = '.') and (srec.attr and fadirectory > 0)then
               FindFile(Path + Srec.Name + '\' + FileName,IncludeSubDirs)
           Until findnext(srec) <> 0;
         end;
         FindClose(SRec);
       end;
     end;

meikl ;-)
Ofcource with *.html it wil not find the subdirs :)
Is there a workaround for this??
That's strange... When Meikl posts comment, I get a notification but not when Vincent posts a comment.

Very odd...


Vincent, I will work it out later...
?? thats really strange
EE is very, VERY buggy, believe me.....
now you got me, eps :-))

but be sure i don't let you runaway :-) (hopefully)

congrates for place 4 in the top 15
Thank you, Meikl. Don't worry, you'll have your 4th place back soon when you catch Raymond   :o)

Vincent, I'm going to work on it now.
Thanks :) I'm going to bed now, so i see the result in the morning.. a good begin of the day ;)
procedure GetFiles(DirStr: string; filelist: TList);
var DirInfo: TSearchRec;
    r : Integer;
    fr: PFile;
    pattern: String;
begin
  pattern := ExtractFileName(DirStr);
  if Pos('*', pattern) > 0 then
    DirStr := ExtractFilePath(DirStr)
  else
    pattern := '*.*';
  if DirStr[Length(DirStr)] <> '\' then
    DirStr := DirStr + '\';
  if SetCurrentDir((DirStr)) then
  begin
    r := FindFirst(pattern, FaAnyfile, DirInfo);
    while r = 0 do
    begin
      if (DirInfo.Attr and faDirectory) = 0 then
      begin
        New(fr);
        fr.filename := DirStr + DirInfo.Name;
        fr.filedate := FileDateToDateTime(DirInfo.Time);
        filelist.Add(fr);
      end;
      r := FindNext(DirInfo);
    end;
    FindClose(DirInfo);
    r := FindFirst('*.*', FaAnyfile, DirInfo);
    while r = 0 do
    begin
      if (DirInfo.Attr and faDirectory) <> 0 then
        if (DirInfo.Name <> '.') and (DirInfo.Name <> '..') then
// comment out the next line to exclude system directories
//          if (DirInfo.Attr and faSysFile) = 0 then
            GetFiles(DirStr + DirInfo.Name + '\' + pattern, filelist);
      r := FindNext(DirInfo);
    end;
    FindClose(DirInfo);
  end;
end;
Now you can use:

c:
c:\
c:\*.*
c:\*.htm
c:\*.*
c:\dir1
c:\dir1\
c:\dir1\*.pas

etc.
Epsylon, you are the best :) many thanks.
You're welcome  :o)