Recursive Directory Walking Routine
Keywords: searcher recursive directories
Below is my version of a directory walking routine. It is about the 10th I have written, and I think the best so far. I only have one modificaiton I want to make, and that is automatic detection of the buffer fulling up and creating a bigger buffer; I think this is about the only downfall of this routine at the moment.WINDOWWARE COMMENT: Ooooooo. Cool. Using stacks in BinaryBuffers. And doing it in so little code too. Very elegant.
For the 32 bit world the SEARCHER extender works, but there is the additional extender baggage to carry around.
Here's the sample code:
; Demo code for a directory walking routine ; This demo calculates the size in bytes of the directory specified, but this routine can been used to delete ; files, apply file permissions, xcopy files etc.... with modification ot the RECURSEDIR routine. ;debug(@ON) totalsize=0 STARTDIRECTORY="C:\incoming\" gosub RECURSEDIR message("debug", "%totalsize% bytes") exit ; Pass the variable STARTDIRECTORY to this function to recurse all the sub directories and run the ProcessDir ; subroutine with all directories. Note all variables used in this set of routines are prefixed by "rd". :RECURSEDIR rdBUFFSIZE=20000 rdOffSet=0 rdStackCount=0 rdDirectory=STARTDIRECTORY rdBinBuf=BinaryAlloc(rdBUFFSIZE) if rdBinBuf==0 Message("Error", "BinaryAlloc Failed") exit endif rdStringList=diritemize("%rdDirectory%\*.*") gosub rdPushList while rdStackCount!=0 gosub rdPopList rdDIRECTORY=rdPopString rdStringList=diritemize("%rdDirectory%\*.*") if itemcount(rdStringList, @tab)!=0 gosub rdPushList endif gosub rdProcessDir endwhile rdDirectory=STARTDIRECTORY gosub rdProcessDir binaryfree(rdBinBuf) return ;This is the routine called to process a directory :rdProcessDir rdFileList=fileitemize("%rdDirectory%\*.*") for rdk=1 to itemcount(rdFileList, @tab) totalsize=totalsize+filesize(strcat(rdDirectory, "\", itemextract(rdk, rdFileList, @tab))) next return ;This routine will push a list of tab delimited strings onto a stack, ;the stack is null deliminated. :rdPushList rdicount=ItemCount(rdStringList, @tab) for rdi=1 to rdicount rdiitem=itemextract(rdi, rdStringList, @tab) rdStackCount=rdStackCount+1 ;If buffer is too full, allocate more space if (rdOffset+strlen(rdiitem)) >= BinaryEODGet(rdBinBuf) rdtempbb=BinaryAlloc(RdBuffSize+20000) BinaryCopy(rdtempbb,0,rdBinBuf,0,rdOffSet) BinaryFree(rdBinBuf) rdBinBuf=rdTempbb rdBuffSize=rdBuffsize+20000 endif rdOffSet=rdOffSet+binarypokestr(rdBinBuf, rdOffSet, strcat(rdDirectory, "\", rdiitem)) rdOffSet=rdOffSet+1 binarypoke(rdBinBuf, rdOffSet-1, 0) next return ;This routine pops a string off the stack and returns it in the variable popstring ;it also decrements the stackcount by one. :rdPopList rdOffSet=rdOffSet-1 rdStackCount=rdStackCount-1 while rdOffset !=0 if binarypeek(rdBinBuf, rdOffSet-1)==0 then break rdOffSet=rdOffSet-1 endwhile rdPopString=binarypeekstr(rdBinBuf, rdOffSet, 512) return
Article ID: W13792Filename: Recursive Directory Walker.txt