Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2008-03

FindFile in sub directories using filter '*.cfg'

6 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

el stamatakos

Hi,
I have a function that has worked quite well in Windows. Now I try to use it on Linux and it does not appear to be going into subdirectories where the files are actually stored. The unit is below. I use the following

FindFile1.Filemask:='*.cfg';
FindFile1.InSubFolders:=True;
FindFile.Path:='/test/sup/Data';

Now in Data there are other directories where the .cfg files reside. I do not know what these directories are since they are created at design time. The program seems to work ok when I give it the exact path but does not when it has to search in sub folders. That is why I had to turn it to true. If anyone knows what is wrong or has another solution that would be great. Thanks

unit FindFile;
interface
uses  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, FileCtrl;
type  TFileAttrKind = (ffaReadOnly, ffaHidden, ffaSysFile, ffaVolumeID, ffaDirectory, ffaArchive, ffaAnyFile);  TFileAttr = set of TFileAttrKind;
  TFindFile = class(TComponent)  private    s : TStringList;
    fSubFolder : boolean;    fAttr: TFileAttr;    fPath : string;    fFileMask : string;
    procedure SetPath(Value: string);    procedure FileSearch(const inPath : string);  public    constructor Create(AOwner: TComponent); override;    destructor Destroy; override;
    function SearchForFiles: TStringList;  published    property FileAttr: TFileAttr read fAttr write fAttr;    property InSubFolders : boolean read fSubFolder write fSubFolder;    property Path : string read fPath write SetPath;    property FileMask : string read fFileMask write fFileMask ;  end;
procedure Register;
implementation
procedure Register;begin  RegisterComponents('About.com', [TFindFile]);end;
constructor TFindFile.Create(AOwner: TComponent);begin  inherited Create(AOwner);  Path := IncludeTrailingBackslash(GetCurrentDir);   FileMask := '*.*';  FileAttr := [ffaAnyFile];  s := TStringList.Create;end;
destructor TFindFile.Destroy;begin  s.Free;  inherited Destroy;end;
procedure TFindFile.SetPath(Value: string);begin  if fPath  Value then  begin    if Value  '' then      if DirectoryExists(Value) then        fPath := IncludeTrailingBackslash(Value);  end;end;
function TFindFile.SearchForFiles: TStringList;begin  s.Clear;  try    FileSearch(Path);  finally    Result := s;  end;end;
procedure TFindFile.FileSearch(const InPath : string);var Rec  : TSearchRec;    Attr : integer;beginAttr := 0;if ffaReadOnly in FileAttr then Attr := Attr + faReadOnly;if ffaHidden in FileAttr then Attr := Attr + faHidden;if ffaSysFile in FileAttr then Attr := Attr + faSysFile;if ffaVolumeID in FileAttr then Attr := Attr + faVolumeID;if ffaDirectory in FileAttr then Attr := Attr + faDirectory;if ffaArchive in FileAttr then Attr := Attr + faArchive;if ffaAnyFile in FileAttr then Attr := Attr + faAnyFile;
if SysUtils.FindFirst(inPath + FileMask, Attr, Rec) = 0 then try   repeat     s.Add(inPath + Rec.Name);   until SysUtils.FindNext(Rec)  0; finally   SysUtils.FindClose(Rec); end;
If not InSubFolders then Exit;
if SysUtils.FindFirst(inPath + '*.*', faDirectory, Rec) = 0 then try   repeat   if ((Rec.Attr and faDirectory)  0)  and (Rec.Name'.') and (Rec.Name'..') then     begin       FileSearch(IncludeTrailingBackslash(inPath + Rec.Name));     end;   until SysUtils.FindNext(Rec)  0; finally   SysUtils.FindClose(Rec); end;end;
end.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.lazarus.freepascal.org/pipermail/lazarus/attachments/20080324/fdcd4126/attachment.html

Reply by email

Graeme Geldenhuys
to el stamatakos
el stamatakos wrote 9 lines
Hi, I have a function that has worked quite well in Windows. Now I try to use it on Linux and it does not appear to be going into subdirectories where the constructor TFindFile.Create(AOwner: TComponent); begin inherited Create(AOwner); Path := IncludeTrailingBackslash(GetCurrentDir); FileMask := '*.*';

The filemask is you problem. Under Linux or any *unix environment, the filemask must be '*' only. If you use '*.*', your directory name must have a '.' somewhere in the name, to be found. '*' covers all names.

I think you can even use the '*' under Windows too, without having to resort to IFDEF's.

I really think FPC should have a AllFiles file mask in the RTL, like it has for Path Delimiters etc... I've created numerous projects where I used IFDEF's to define a cAllFiles constant for specific platforms.

Regards,
- Graeme -

_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/

Reply by email

Graeme Geldenhuys
to el stamatakos: I have a function that has worked quite well in Windows. Now I try to use it on Linux and…
el stamatakos wrote 7 lines
Hi, I have a function that has worked quite well in Windows. Now I try to use it on Linux and it does not appear to be going into subdirectories where the files are actually stored. The unit is below. I use the following FindFile1.Filemask:='*.cfg';

Also remember that Linux is case-sensitive, so if you have files ending in .CFG or .Cfg etc, it will not be found with the '*.cfg' mask. To make Find Files case-insensitive, you need to find all files, convert the resulting filename to lowercase and do a file extension comparison with 'cfg'. If you find a match, then add it to some FileList class which you can return to the calling procedure.

For code on how to do this, have a look in the fpGUI Toolkit source code available on SourceForge. The TfpgFileGrid class in src/gui/gui_grid.pas unit.

Regards,
- Graeme -

_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/

Reply by email

Mattias Gaertner
to Graeme Geldenhuys: The filemask is you problem. Under Linux or any *unix environment, the filemask must be…
Show quoted text 24 lines
On 25/03/2008, el stamatakos wrote: > > Hi, > I have a function that has worked quite well in Windows. Now I > try to use it on Linux and it does not appear to be going into > subdirectories where the constructor TFindFile.Create(AOwner: > TComponent); begin > inherited Create(AOwner); > Path := IncludeTrailingBackslash(GetCurrentDir); > FileMask := '*.*'; The filemask is you problem. Under Linux or any *unix environment, the filemask must be '*' only. If you use '*.*', your directory name must have a '.' somewhere in the name, to be found. '*' covers all names. I think you can even use the '*' under Windows too, without having to resort to IFDEF's. I really think FPC should have a AllFiles file mask in the RTL, like it has for Path Delimiters etc... I've created numerous projects where I used IFDEF's to define a cAllFiles constant for specific platforms.

AllFilesMask

Mattias

Reply by email

Graeme Geldenhuys
to Mattias Gaertner
Mattias Gaertner wrote 9 lines
> I really think FPC should have a AllFiles file mask in the RTL, like > it has for Path Delimiters etc... I've created numerous projects > where I used IFDEF's to define a cAllFiles constant for specific > platforms. AllFilesMask Mattias

Exactly my point. Lazarus has that defined, fpGUI has that defined and I'm pretty sure MSEgui has it defined as well. That constant should really be defined in Free Pascal's RTL, so everybody can use it!

Regards,
- Graeme -

_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/

Reply by email

bb
to el stamatakos: I have a function that has worked quite well in Windows. Now I try to use it on Linux and…
el stamatakos wrote 10 lines
Hi, I have a function that has worked quite well in Windows. Now I try to use it on Linux and it does not appear to be going into subdirectories where the files are actually stored. The unit is below. I use the following FindFile1.Filemask:='*.cfg'; FindFile1.InSubFolders:=True; FindFile.Path:='/test/sup/Data';

As others allready pointed out there are two problems. Firts the mask (*.* vs *) secondly the case-sensitivity.
I wrote some class like you did that solves these problems. It will let you specify if the mask is linux or windows style, and it uses an extended version of TMask to do filename matching. This will let you specify wether the mask is case sensitive. (as anadded bonus my class also excepts an exclusion mask, to exlude files from the serach, and it will let you use sets (like [a..d,y,z] in filemask).
I tested it on Linux and Win32.
I could mail it (or put it somewhere on the web for you) if you're interested.

Bart
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.lazarus.freepascal.org/pipermail/lazarus/attachments/20080325/74f68811/attachment.html

Reply by email