'=========================================================================== ' Subject: RECURSIVE FILE FIND ROUTINE Date: 03-10-99 (19:43) ' Author: Dieter Folger Code: PB ' Origin: folger@bamberg.baynet.de Packet: PB.ABC '=========================================================================== '---------------------------------------------------------------------------- ' FINDFILE.BAS for PowerBasic ' Fast file search in specified dir and its subdirs. ' Found files are shown with name, size, date, time, attrib, and long ' filename (if possible). Summery reports number of found files, total ' bytes of files and number of subdirs. ' "C:\" as Path$ and "*.*" as Mask$ show all files on this drive (any ' attribute). ' Freeware (c) 1997-99 by Dieter Folger '-- Note: ------------------------------------------------------------------- ' A former version of this program worked recursivly, but the increasing ' harddisk capacity multiplied the number of subdirectories on a drive ' enormously. There was a stack error when too many recursions had to be ' done (= subdirs scanned), even with the stack set to maximum size (32766). ' This version uses the GOTO command instead, which is less elegant but ' avoids a stack error. ' Demo program searches for all files (*.*) in current directory and its ' subdirs. '---------------------------------------------------------------------------- DEFINT A-Z Path$ = CURDIR$ + "\" P$ = Path$ ' save path name as it is changed by SearchTree Mask$ = "*.*" ' all files, any attribute CLS SearchTree Path$, Mask$ PRINT "Path ";P$;Mask$;FileFound;"files found -";DirFound;"subdirs scanned" DSize$=LTRIM$(USING$(",############",DSize&)) REPLACE "," WITH "." IN DSize$ ' German conversion PRINT DSize$;" bytes used by these files" END '---------------------------- SUB SearchTree (Path$, Mask$) '---------------------------- DIM DTABuffer$(100), P$(100) SHARED FileFound, DirFound, DSize&, d IF RIGHT$(Path$,1) <> "\" THEN Path$ = Path$ + "\" ' makes sure that Path$ ' ends with backlash LNames = Lfn ' Check if long filenames are supported ' Comment the line if you don't want long names Again: ' Jump here for more dirs and files search SaveDTA ' save current DTA for later use F$ = DIR$(Path$ + Mask$, 7) ' get all types of files, any attr IF LEN(F$) THEN PRINT "DIR "; Path$; IF LNames THEN PRINT " (";DirLn$;")" ELSE PRINT ' show long name of dir END IF WHILE LEN(F$) ' repeat until no more files are found in this dir INCR FileFound FileStuff Fs&, Fd$, Ft$, Att$ PRINT USING " \ \";F$; FSize$ = USING$(",##########",Fs&) REPLACE "," WITH "." IN FSize$ ' German conversion PRINT FSize$;" ";Fd$;" ";Ft$;" ";Att$; " "; IF LEN(F$) THEN IF Lnames THEN PRINT LongName$(Path$+F$) ELSE PRINT Dsize& = Dsize& + Fs& ' add filesize to dirsize F$ = DIR$ 'get next file IF INKEY$ = CHR$(27) THEN END 'if user wants to cancel WEND D$ = DIR$(Path$ + "*.*", 55) ' search for all subdirs, any attr INCR d: P$(d) = Path$ ' save current path DO IF LEN(D$) AND (Attr? AND 16) = 16 THEN ' directory found IF Lnames THEN DirLn$ = LongName$(Path$+"\"+D$) ' long name of dir Path$ = RTRIM$(Path$,"\") + "\" + D$ + "\" INCR DirFound ' count dir for summery GOTO Again ' start search loop again in this dir END IF D$ = DIR$ ' next dir IF D$ = "" THEN ' no more subdirs DECR d : Path$ = P$(d) ' restore old path and RestoreDTA ' old DTA to continue search END IF IF INKEY$ = CHR$(27) THEN END LOOP UNTIL d = 0 END SUB '---------------------------- SUB GetDTA (DTASeg&, DTAOfs&) '---------------------------- ! mov ax, &h2F00 ! int &h21 ! mov s&,es ! mov o&,bx DTAOfs& = o&:DTASeg& = s& END SUB '------------- FUNCTION Attr? '------------- GetDTA DTASeg&, DTAOfs& DEF SEG = DTASeg& Attr? = PEEK(DTAOfs& + 21) DEF SEG END FUNCTION '------------------------------------------- SUB FileStuff (FSize&, FDate$, FTime$, Att$) '------------------------------------------- GetDTA DTASeg&, DTAOfs& DEF SEG = DTASeg& FSize& = PEEKL(DTAOfs& + 26) FDate$ = FILEDATE$(PEEKI(DTAOfs& + 24)) FTime$ = FILETIME$(PEEKI(DTAOfs& + 22)) Att? = PEEK(DTAOfs& + 21) DEF SEG Att$ = "...." IF BIT(Att?, 0) THEN MID$(Att$, 2, 1) = "R" 'read only IF BIT(Att?, 1) THEN MID$(Att$, 3, 1) = "H" 'hidden IF BIT(Att?, 2) THEN MID$(Att$, 4, 1) = "S" 'system IF BIT(Att?, 5) THEN MID$(Att$, 1, 1) = "A" 'archive END SUB '---------- SUB SaveDTA '---------- SHARED d, DTABuffer$() GetDTA DTASeg&, DTAOfs& DEF SEG = DTASeg& DTABuffer$(d) = PEEK$(DTAofs&, 21) DEF SEG END SUB '------------- SUB RestoreDTA '------------- SHARED d, DTABuffer$() GetDTA DTASeg&, DTAOfs& DEF SEG = DTASeg& POKE$ DTAofs&, DTABuffer$(d) DEF SEG END SUB '-------------------------- FUNCTION FileDate$ (FDate) '-------------------------- 'Convert DOS date to string DateY = (FDate \ 512) + 80 Year$ = RIGHT$("00" + MID$(STR$(DateY), 2), 2) DateM = (FDate AND 511) \ 32 Month$ = RIGHT$("00" + MID$(STR$(DateM), 2), 2) DateD = FDate AND 31 Day$ = RIGHT$("00" + MID$(STR$(DateD), 2), 2) FileDate$ = Day$ + "." + Month$ + "." + Year$ END FUNCTION '-------------------------- FUNCTION FileTime$ (FTime) '-------------------------- 'Convert DOS time to string TimeH = FTime \ 2048 IF TimeH < 0 THEN INCR TimeH, 31 Hour$ = RIGHT$("00" + MID$(STR$(TimeH), 2), 2) TimeM = (FTime AND 2047) \ 32 Minute$ = RIGHT$("00" + MID$(STR$(TimeM), 2), 2) FileTime$ = Hour$ + ":" + Minute$ END FUNCTION '----------- FUNCTION Lfn '----------- ' checks if Windows is installed ' (= if long file names are supported) ! mov ax, &h1600 ! int &h2F ! mov LfMode, al IF LfMode > 3 THEN FUNCTION = LfMode END FUNCTION '------------------------- FUNCTION LongName$ (File$) '------------------------- ' Returns long filename of File$ DIM Ldta AS STRING * 500 DIM FindHandle AS Byte F$ = File$ + CHR$(0) LSeg = VARSEG(Ldta) LOff = VARPTR(Ldta) FSeg = STRSEG(F$) FOff = STRPTR(F$) ! push ds ! mov ax, &h714E ;find first matching file ! mov si, 0 ;see Ralph Brown's ! mov cx, &hFF ;interrupt list ! mov es, LSeg ;for further details ! mov di, LOff ! mov dx, FOff ! mov ds, FSeg ! int &h21 ! pop ds ! mov FindHandle, ax ! mov ax, &h71A1 ;terminate search and ! mov bx, FindHandle ;reset file handle ! int &h21 FUNCTION = RTRIM$(MID$(Ldta,45,260), CHR$(0)) END FUNCTION '==== eof ==================================================================