Listing+the+contents+of+a+directory

//by Richard Russell, March 2010//

The main //BBC BASIC for Windows// documentation explains how to [|list the contents of a disk directory] and more detail is provided in the article Scanning a Directory (Reading Directory Entries), but both require the code to be adapted to the needs of the programmer. Some dialects of BASIC provide a built-in means of extracting the contents of a directory to a string array, for example Liberty Basic's **FILES** statement; this can be a more straightforward approach and avoids the need to work directly with the Windows API.

The function **FNfiles** listed below provides a similar capability in BBC BASIC. It takes two parameters, a **filter** string to determine the directory (folder) and files to be scanned, and an array in which to return the results, for example: code format="bb4w" nfiles% = FNfiles("C:\Windows\*.*", file$) code Here the array **file$** is filled with a list of all the files and sub-directories in **C:\Windows\** (starting at index zero), and the total number of entries is returned from the function. For each file or directory four items of information are returned as follows: The main attribute bits are (in hexadecimal): If necessary the array will be created by the function; it is not essential to DIMension it yourself. However if the array already exists, but is not big enough to contain the data, it will be discarded and a new array created. Since this will result in memory being lost, if you intend to call the function multiple times it is better to create an array big enough to hold the largest amount of data you are likely to need, for example: code format="bb4w" DIM file$(1000,3) nfiles% = FNfiles("C:\Windows\*.*", file$) code If you want to list only a certain type of file, you can specify the filter string accordingly: code format="bb4w" nfiles% = FNfiles("C:\Program Files\BBC BASIC for Windows\*.exe", file$) code The function may also be used as a means of detecting the existence of a file: code format="bb4w" exists% = FNfiles("C:\pagefile.sys", file$) code This will return **1** if the file exists and **0** otherwise.
 * file$(I%,0) || The name of the file or sub-directory||
 * file$(I%,1) || The size of the file, as a decimal string||
 * file$(I%,2) || The 'last modified' time stamp, in TIME$ format ||
 * file$(I%,3) || A set of attribute bits, as a hexadecimal string||
 * 01 || Read only ||
 * 02 || Hidden ||
 * 04 || System ||
 * 10 || Directory ||
 * 20 || Archive ||

Here is the function itself: code format="bb4w" DEF FNfiles(filter$, RETURN array$) LOCAL @%, D%, H%, I%, N%, P%, R%, S%, T%, size# DIM D% LOCAL 317, S% LOCAL 15, T% LOCAL 24 @% = &1001010     IF !^array$ N% = DIM(array$,1)+1 FOR P% = 0 TO 1 I% = 0 SYS "FindFirstFile", filter$, D% TO H%       IF H% <> -1 THEN REPEAT IF P% THEN size# = D%!28 * 2.0#^32 + (D%!32 >>> 1)*2 + (D%!32 AND 1) SYS "FileTimeToSystemTime", D%+20, S%             SYS "GetDateFormat", 0, 0, S%, "ddd.dd MMM yyyy,", T%, 17 SYS "GetTimeFormat", 0, 0, S%, "HH:mm:ss", T%+16, 9 array$(I%,0) = $$(D%+44) array$(I%,1) = STR$(size#) array$(I%,2) = $$T% array$(I%,3) = STR$~!D% ENDIF I% += 1 SYS "FindNextFile", H%, D% TO R%         UNTIL R% = 0 SYS "FindClose", H%       ENDIF IF P% = 0 IF N% < I% THEN IF N% array$ = "" !^array$ = 0 DIM array$(I%-1,3) ENDIF NEXT P%     = I% code