Sei sulla pagina 1di 6

CodeGear (Borland): Delphi - findfirst - findnext

Pgina 1 de 6

Smart questions Smart answers Smart people

Go

Find A Forum

Go

Join Directory Search Tell A Friend Whitepapers Jobs

Home > Forums > Programmers > Development Tools > CodeGear (Borland): Delphi Forum thread102-1512569

findfirst - findnext

www posgraduacao-cursos com br

Anncios Google

lorife (Programmer)

11 Nov 08 3:40

Hi, i'm referring to the thread thread102-1418012: FindFirst/FindNext. please could you help me using sfindfirst to: 1) retrieve ALL directories and NO Files(hidden and system too, everything..) 2) retrieve ALL files and NO directories (hidden and system too, everything..) i wish to retrieve exactly what i want, without use "if ((SR.Attr and faDirectory) <> 0)" how can i do?

Glenn9999 (Programmer)

11 Nov 08 14:56

Attributes are retrieved in a value with a set of flags that must be tested for to determine these things. There really isn't any way to get past that. Even the code from the thread does that. 1. This would be anything with a directory attribute. What you want is:

CODE

if (SR.Attr and faDirectory) = faDirectory

The code from the thread does it too, if you specify faDirectory 2. In this case you want anything that is NOT a directory. In sense you want this in your code when using faAnyfile as a filter attribute:

CODE

if (SR.Attr and faDirectory) <> faDirectory

There's really no way getting around interrogating the bits of the attribute value to find out these things.
---------Measurement is not management.

MilesAhed (Programmer)

9 Dec 08 18:35

It's been my experience that often even if you check the attribute when scanning folders with "*.*" it's just about impossible to do stuff like add only folders to a list. I wasted about 6 hours trying to do it in Delphi 5 one day. I suspect FindFirst/FindNext is largely broken. Either that or there's some hidden trick like zeroing out the structure between each call or something. Sure doesn't work as expected. You

http://www.tek-tips.com/viewthread.cfm?qid=1512569

27/3/2011

CodeGear (Borland): Delphi - findfirst - findnext

Pgina 2 de 6

might try one of those old "Undocumented Windows API" books if you can still find them.

lorife (Programmer)

10 Dec 08 3:05

thank you to everyone for the answer...i received just today the notification of both replies... Anyways i think it's broken too! :)

roo0047 (Programmer)

10 Dec 08 13:25

Quote:

FindFirst/FindNext is largely broken

I have to strongly disagree. I've been using TSearchRec and the FindFirst/FindNext successfully since Turbo Pascal, including Delphi versions 4,5 & 7 without any problem. It does require an understanding of parameter Attr and how it's logic works. All of which are explained in Delphi Help under topic "FindFirst". Below is a snippet from one of my more recent apps which uses it to search directories.
CODE

procedure TPastDueInvoices.FillDueCustList; var sr: TSearchRec; rc: integer; DueCList: TStringList; OverDueList: TStringList; function InOverDueList(Customer: string): boolean; var i: integer; begin result:= false; for i:= 0 to OverDueList.Count - 1 do if pos(Customer, OverDueList[i]) > 0 then result:= true end; begin DueCList:= TStringList.Create; OverDueList:= TStringList.Create; OverDueList.LoadFromFile(CollectionsFolder + 'OpenInvoices.txt'); rc:= FindFirst(CollectionsFolder + '*.*', faDirectory, sr); try while rc = 0 do begin if (SR.Attr And faDirectory) = faDirectory then if (sr.Name <> '.') and (sr.Name <> '..') then if InOverDueList(sr.Name) then DueCList.Add(sr.Name); rc:= FindNext(sr); end; finally FindClose(sr); Memo1.Lines.Assign(DueCList); FreeAndNil(DueCList); FreeAndNil(OverDueList); end; end; This may help you understand - The file attribute constants and their values are: faReadOnly = 1 faHidden = 2 faSysFile = 4 faVolumeID = 8 faDirectory = 16 faArchive = 32 faAnyFile = 63 faReadOnly + faHidden + faSysFile + faVolumeID + faDirectory + faArchive = faAnyFile or 1+2+4+8+16+32:=63;

http://www.tek-tips.com/viewthread.cfm?qid=1512569

27/3/2011

CodeGear (Borland): Delphi - findfirst - findnext

Pgina 3 de 6

So a hidden directory is: (2 and 16) See also "Boolean operators" in Delphi Help. HTH

Roo Delphi Rules!

roo0047 (Programmer)

10 Dec 08 13:44

It's also worth noting that FindFirst must also include the directory to start looking in. You can also (or must) do recursive calls to search for subdirectories within each directory (or folder).
Roo Delphi Rules!

lorife (Programmer)

10 Dec 08 15:03

hi, in the 1st topic I was talking about sfindfirst, not findfirst..which is a function Glenn9999 made. however i know that fadirectory returns just directory...the problem is that there is no way to use findfirst to return just files (no directories) and you need to manually check the attributes using: if (SR.Attr and faDirectory) <> faDirectory What i mean is that if i have 1 file and 100 directory findfirst returns 101 results....unless you use sfindfirst (which works to retrieve just files but does not work if i want to retrieve just directories!)

sggaunt (Programmer)

11 Dec 08 6:15

findfirst isnt Glenns routine perhaps you have this the wrong way around. Eitherway the code below manages to get just the folders using findfirst then build an explorer like tree. This code based on a tutorial on using the treeview by Hugh Collingbrook (PCPlus magazine)

CODE

procedure TNetBackup.addSubDirs( rootDir : string; Node : TTreeNode; Tree: integer); var SearchRec: TSearchRec; Result : integer; NewNode : TTreeNode; begin // find first file, Result is 0 if successful Result := FindFirst(rootDir + '*.*', faDirectory, SearchRec); while Result = 0 do begin if browser.isDirectory(SearchRec) then begin // if directory is found add it as a child of prev node in TreeView if tree = 0 then NewNode := Folders.Items.AddChild(Node, SearchRec.Name) else NewNode := DestFolders.Items.AddChild(Node, SearchRec.Name); NewNode.SelectedIndex := 1; if (browser.hasSubDirectories( rootDir + SearchRec.Name ) ) then NewNode.HasChildren := true; end; // then continue searching } Result := FindNext(SearchRec); end;

http://www.tek-tips.com/viewthread.cfm?qid=1512569

27/3/2011

CodeGear (Borland): Delphi - findfirst - findnext

Pgina 4 de 6

FindClose(SearchRec); Node.AlphaSort; end;

Isdirectory does indeed check the attribute field

CODE

function TBrowser.IsDirectory( sr : TSearchRec ) : boolean; // test if current file is a directory begin isDirectory := ((sr.Attr and faDirectory > 0) and (sr.Name <> '.') and (sr.Name <> '..')); end;

Has subdirectories looks like this

CODE

function TBrowser.hasSubDirectories( d : string ) : boolean; // test in the directory indicated by the string 'd' contains // subdirectories. If so, return true. var SearchRec: TSearchRec; SResult : integer; noSubDirFound : boolean; begin // find first file, Result is 0 if successful noSubDirFound := true; SResult := FindFirst(d + '\*.*', faDirectory, SearchRec); while ((SResult = 0) and (noSubDirFound)) do begin if isDirectory(SearchRec) then noSubDirFound := false; SResult := FindNext(SearchRec); end; FindClose(SearchRec); hasSubDirectories := (noSubDirFound = false); end;

whosrdaddy (Vendor)

11 Dec 08 7:22

Quote (lorife):

however i know that fadirectory returns just directory...the problem is that there is no way to use findfirst to return just files (no directories)

what is wrong with: Result := FindFirst(rootDir + '*.*', 0, SearchRec); which will search for all normal files (ie not having read-only, hidden or archive flag) the inverse is true, if you want only directories, then you must test the faDirectory bit /Daddy

----------------------------------------------------What You See Is What You Get Never underestimate tha powah of tha google!

roo0047 (Programmer)

11 Dec 08 10:53

http://www.tek-tips.com/viewthread.cfm?qid=1512569

27/3/2011

CodeGear (Borland): Delphi - findfirst - findnext

Pgina 5 de 6

I can't speak for Glenn, but he may have discovered that wrapping every possible search scenario into a single process would be a bit overwhelming. Since he never posted a FAQ from this, I can only assume his attempt was incomplete. The best bit of information (IMO) in the thread you referenced was from Griffyn:
Quote:

I also use the faAnyFile and post-filter.

The simplest approach is to write your own search, search for everything, and throw out what you don't want (post-filter) as Glenn pointed out in this thread. My point was "it ain't broken" where "it" = FindFirst/FindNext.
Roo Delphi Rules!

roo0047 (Programmer)

11 Dec 08 11:03

FYI - My last post was sitting 'un-sent' all night in my editor and was then sent this AM before reading any of the subsequent posts. Thank you 'unknown' for the star!
Roo Delphi Rules!

Glenn9999 (Programmer)

11 Dec 08 15:00

Quote:

I can't speak for Glenn, but he may have discovered that wrapping every possible search scenario into a single process would be a bit overwhelming. Since he never posted a FAQ from this, I can only assume his attempt was incomplete.

As was said in the original thread, thread102-1418012: FindFirst/FindNext , the only real incentive was to try and turn out something that would be a lot more predictable than the original Sysutils findfirst/findnext. You can see that from the initial question in the thread. I ultimately did some playing around and came up with what was posted within that thread, which has "must have" processing as opposed to "may have" processing. I would guess that is the difference and results in (IMO the bug since DOS days) the specified attr being irrelevant. As the question could come out in the posts: "What is the point of specifying attr, if I have to post-filter?" The code was only posted to be something enlightening, not really anything for FAQ material (though I can make it that way with a couple of extra notes - see *). Sysutils is very similar - as you can see in the code, the Windows FindFirst/FindNext filters nothing. The code in the thread (and Sysutils for that matter) does that job. I would have to try it with the code I posted, but it might be interesting to see if it works by specifying "not faDirectory" for this OP's second question. * - as most people code their own filters anyway, using faAnyFile, there is a lot of code in Sysutils.FindFirst and Sysutils.FindNext that gets run for basically no purpose. For this case, it's certainly better for efficiency sake to recode FindFirst/FindNext to simply call the Windows variants (without Attr in the function parms) and simply move the record data. This might be something to investigate if such a FAQ were to be written.
---------Measurement is not management.

Glenn9999 (Programmer)

15 Dec 08 2:27

Quote:

Since he never posted a FAQ from this

Done. More of a generic document on how FindFirst & FindNext works, but hopefully it will be interesting to someone.

http://www.tek-tips.com/viewthread.cfm?qid=1512569

27/3/2011

CodeGear (Borland): Delphi - findfirst - findnext

Pgina 6 de 6

FAQ102-7116: Understanding FindFirst and FindNext


---------Measurement is not management.

DELPHI VCL label's editor print barcodes GS1 128 2D PDF417 easy mailing and shipping labels
www.mesurasoft.com/Plabel.aspx

Join | Jobs | Advertise | About Us | Contact Us | Site Policies


Copyright 1998-2011 Tecumseh Group, Inc. All rights reserved. Unauthorized reproduction or linking forbidden without express written permission.

http://www.tek-tips.com/viewthread.cfm?qid=1512569

27/3/2011

Potrebbero piacerti anche