Any better source code to search for file/folder

hi all,
I've just finished a small program to search some filetype on my harddisk. The code run very well but it seems to me that it 's a bit too.... lenghy. Is there anyway else to search file without having to use ADIR function?

*//CODE

? SearchFile("D:","mp3") &&This will show the number of all mp3 files found on drive D:

*//Contain of file SearchFile.PRG
parameters cStartFolder, cExtention
private _nCount
store 0 to _nCount
dimension _sFound[1,1]
store '' to _sFound
do Search4Files with cStartFolder, cExtention
*//command to do something with a list of file stored in array _sFound

return _nCount
*//
procedure Search4Files(cFolder as string , cExtention as string)
local cUniqueName
private _afile, _afolder,i, j, cSubFolder
cUniqueName=sys(2015)
_afile=cUniqueName+"_F0"
_afolder=cUniqueName+"_D0"
dimension &_afile[1,5], &_afolder[1,5]
store "" to &_afile, &_afolder
if directory(cFolder) and !cFolder=="." and !cFolder==".."
if adir(&_afile,cFolder+"\*."+cExtention)>0 && found, add filename to array and text file
for i=1 to alen(&_afile,1)
do AddFile with cFolder+"\"+&_afile[i,1]
doevents
endfor
endif
if adir(&_afolder, cFolder+"\*.*","DHRS")>2
for j=3 to alen(&_afolder, 1)
doevents
if "D" $ &_afolder[j,5] and !&_afolder[j,1]=="." and !&_afolder[j,1]==".."
cSubFolder=cFolder+"\"+&_afolder[j,1]
if directory(cSubFolder)
wait window "Looking in '"+lower(cSubFolder) +"'..." nowait
*// write the folder's name to a text file on drive C:
=strtofile(lower(cSubFolder)+chr(13)+chr(10),"c:\Folders.txt",1)
do Search4Files with cSubFolder, cExtention
endif
endif
endfor
endif
endif
return
endproc
*//--
procedure AddFile (cFileToAdd as string) as Boolean
if type('cFileToAdd')='C' and !empty(cFileToAdd)
nAddRow=iif(empty(_sFound[1,1]),0,1)+alen(_sFound,1)
dimension _sFound[nAddRow,1]
_sFound[nAddData,1]=cFileToAdd
*// Append filename to a text file on drive C:
=strtofile(lower(cFileToAdd)+chr(13)+chr(10),"c:\FoundThem.txt",1)
_nCount=_nCount+1
return .t.
else
return .f.
endif
endfunc

[2388 byte] By [kanguru] at [2008-2-26]
# 1

I prefer Filer.dll that ships with VFP. It can search multiple extensions at a time, supports things like contains 'text', doesn't have array limits based on VFP version etc. ie:
[code]
lnFiles = GetTree(Getdir(),'*.vc*',.T.)
Browse

Function GetTree
Lparameters tcStartDir,tcSkeleton,tlSubfolders, ;
tcSearchText1, tcSearchText2, tcSearchText3, ;
tlSearchAnd, tlWholeWords, tlWithCase
tcStartDir = Iif(Empty(m.tcStartDir),Sys(5)+Curdir(),m.tcStartDir)
tcSkeleton = Iif(Empty(m.tcSkeleton),'*.*',m.tcSkeleton)
tcSearchText1 = Iif(Empty(m.tcSearchText1), '', m.tcSearchText1)
tcSearchText2 = Iif(Empty(m.tcSearchText2), '', m.tcSearchText2)
tcSearchText3 = Iif(Empty(m.tcSearchText3), '', m.tcSearchText3)

Create Cursor filelist ;
(filepath c(50), filename c(20), ;
filesize i, fattr c(8), createtime T, lastacc T, lastwrite T)
oFiler = Createobject('filer.fileutil')
With oFiler
.SearchPath = m.tcStartDir
.SearchText1 = m.tcSearchText1
.SearchText2 = m.tcSearchText2
.SearchText3 = m.tcSearchText3
.SearchAnd = Iif(m.tlSearchAnd,1,0)
.IgnoreCase = Iif(m.tlWithCase,0,1)
.WholeWords = Iif(m.tlWholeWords,1,0)
.Subfolder = m.tlSubfolders && Check subfolders
.SortBy = 5 && Sort by LastWriteTime
.SortDirection = 1 && Descending 0-Ascending
.FileExpression = tcSkeleton && Search for skeleton
.Find(0)

For ix=1 To .Files.Count
With .Files(ix)
If !(Bittest(.Attr,4) And .Name = '.')
Insert Into filelist ;
(filepath, filename, filesize, fattr, createtime, lastacc, lastwrite) ;
values ;
(.Path, .Name, .Size, Attr2Char(.Attr), ;
Num2Time(.Datetime), Num2Time(.LastAccessTime), Num2Time(.LastWriteTime))
Endif
Endwith
Endfor
Return .Files.Count
Endwith

Function Num2Time
Lparameters tnFloat
Return Dtot({^1899/12/30}+Int(m.tnFloat))+86400*(m.tnFloat-Int(m.tnFloat))

Function Attr2Char
Lparameters tnAttr
Return ;
IIF(Bittest(m.tnAttr,0),'RO','RW')+;
IIF(Bittest(m.tnAttr,1),'H','_')+;
IIF(Bittest(m.tnAttr,2),'S','_')+;
IIF(Bittest(m.tnAttr,4),'D','_')+;
IIF(Bittest(m.tnAttr,5),'A','_')+;
IIF(Bittest(m.tnAttr,6),'E','_')+;
IIF(Bittest(m.tnAttr,7),'N','_')
[/code]

CetinBasoz at 2007-9-8 > top of Msdn Tech,Visual FoxPro,Visual FoxPro General...
# 2

Thanks CetinBasoz

I have tried your code and relized that filer.dll is a very powerful searching tool and ready-to-use. This is exactly what i'm looking for.

kanguru at 2007-9-8 > top of Msdn Tech,Visual FoxPro,Visual FoxPro General...
# 3
With deference to speed and total amount of code, you might find the following worthwhile...

LOCAL lcDrv, lcExt, lcQuery, loFile, loWinMgmts, colFiles, loFSO
lcDrv = "D:" && Drive to be searched
lcExt = "mp3" && txt, exe, or whatever
lcQuery = "select * from cim_datafile where Drive='" + ;
lcDrv + "' and Extension = '" + ;
lcExt + "'" && Path= FileName= && Remember to use \\ for paths
loWinMgmts = GETOBJECT("winmgmts:")
colFiles = loWinMgmts.execquery(lcQuery)
loFSO = CreateObject("Scripting.FileSystemObject")
CLEAR && just blank it out for our output below
FOR EACH loFile IN colFiles
?loFile.NAME
NEXT
?"Done!"

CraigSBoyd at 2007-9-8 > top of Msdn Tech,Visual FoxPro,Visual FoxPro General...
# 4

Thankyou Craig S

CreateObject("Scripting.FileSystemObject"). This is one of many ways to search for files and folders. Although the code is extreamly short but this way is pretty slow compare to the way of using ADIR and filer.dll.
I tested to search for more than 3000 mp3 files on my PC locate in 151 diffrent folders.
Scripting.FileSystemObject took 34 secs to finish. With filer.dll, it took 3 secs and using code with ADIR( ) function took more than 4 secs. Anyway, now i'm doing some search to find out what FileSystemObject can do?
Thankyou again Craig S

kanguru at 2007-9-8 > top of Msdn Tech,Visual FoxPro,Visual FoxPro General...
# 5
Those are interesting results you got on speed. I have a drive with just under 4000 folders and it takes around 30 seconds to search them all for txt files. I don't know why it would run so slow on your computer. I guess there are many factors that could effect it. If I get some extra time, I will run some speed tests on this scripting code vs recursive function vs filer on my own system (I appreciate your including the benchmarks you recorded - you've got me curious now). It appears on your system that adir or filer are definately the way to go. <g>
CraigSBoyd at 2007-9-8 > top of Msdn Tech,Visual FoxPro,Visual FoxPro General...
# 6

Recursion is definitely faster, just like you said. I ran the following code and ended up with an increase in speed of 6 magnitudes...

x = SECONDS()
=GetAllFiles("D:\", "mp3")
? "Recursive: " + TRANSFORM(SECONDS() - x)

FUNCTION GetAllFiles(cDirectory, tcExt)
LOCAL ARRAY aryTemp(1,5)
LOCAL nCount, nMax, nLen, cFile
SET DEFAULT TO (cDirectory)
=ADIR(aryTemp, "*.*","AHRSD",1)
nMax = ALEN(aryTemp,1)
FOR nCount = 1 TO nMax
cFile = ALLTRIM(aryTemp(nCount,1))
IF !(cFile == ".") AND !(cFile == "..")
IF "D" $ aryTemp(nCount,5)
=GetAllFiles(ADDBS(cDirectory + cFile), tcExt)
ELSE
IF LOWER(JUSTEXT(cFile)) == LOWER(tcExt)
? cDirectory + cFile
ENDIF
ENDIF
ENDIF
ENDFOR
ENDFUNC

CraigSBoyd at 2007-9-8 > top of Msdn Tech,Visual FoxPro,Visual FoxPro General...
# 7

Dear CraigSBoyd

Your post confused me a little bit. I intended to test again if you've not post your test result here. I'm looking for some way to manage files in VFP that support filename with special characters such as:
"Hà N?i Ni?m Tin Và Hy V?ng.mp3"
UpperCase should be "Hà N?I NI?P TIN Và HY V?NG.MP3"
"Vi?t Nam Quê H??ng T?i.mp3"
UpperCase should be "VI?T NAM QUê H??NG T?I.MP3"
You know, such filename as above when renamed or copied with VFP, VFP converts all characters to lower case. Use ADIR function in VFP it will store filename to array in UpperCase. But the function LOWER, UPPER in VFP can not use for special unicode characters. It convert unreadable unocode to "?". for instance "Hà N?i Ni?m Tin Và Hy V?ng.mp3".
Do you know anyway to use Unicode-UTF8 with VFP? I 've search alot but found nothing useful!
Thankyou

kanguru at 2007-9-8 > top of Msdn Tech,Visual FoxPro,Visual FoxPro General...
# 8
> Do you know anyway to use Unicode-UTF8 with VFP?

VFP cannot work with Unicode. Whenever you have a Unicode string, VFP converts it to ANSI using the current application codepage and locale. There are some parts in VFP that allow you to work with UTF-8 instead of ANSI, but these only affect access to COM objects.

If you want to manipulate Unicode strings, you have to use API functions. In the following sample, lower.txt contains the string in Unicode format. I created the file by copying your sample into Notepad and saving the textfile as a unicode file.

Declare LONG _wcsupr in MSVCRT.dll String @
lcString =
Substr(FileToStr("lower.txt"),3)
_wcsupr( @lcString )
StrToFile(lcString,"upper.txt",2)

ChristofWollenhaupt at 2007-9-8 > top of Msdn Tech,Visual FoxPro,Visual FoxPro General...