DIR$ function  

Purpose

Return a filename and/or directory entry that matches a file name mask and an optional attribute.

Syntax

file$ = DIR$(mask$ [, [ONLY] attribute&, TO DirDataVar])
file$
= DIR$([NEXT] [TO DirDataVar])

Remarks

There are two forms to the DIR$() function.  The first form, which includes a mask string and optional attribute, is used to find the first filename which matches.  The second form, without those parameters, returns subsequent matching filenames.  When the returned string is null (zero-length), there are no further matching filenames.

The second form may optionally specify the key-word NEXT to aid in self-documentation of the source code.

mask$ specifies a filename or path which can include a drive name and system wildcard characters (* and ?).  If the numeric attribute parameter is zero (or not specified), DIR$ returns only "Normal" files.  If mask$ is a null (zero-length) string, the function call is equivalent to the second form of the function to find subsequent matching filenames.  In that case, an optional attribute is ignored.

If an attribute& is specified, it must use a standard operating system numeric attribute code.  This causes DIR$ to include filenames with specific attributes in the search, in addition to normal files. "Normal" files are those which are not hidden or system files, nor are they a directory or a volume label.

Attribute

Description

Equate

 0

Normal

%NORMAL

 2

Hidden

%HIDDEN

 4

System

%SYSTEM

 8

Volume Label

%VLABEL

16

Directory

%SUBDIR

You can search for filenames with multiple attributes set by adding the attribute codes together.  For example, to search for hidden and system files, you'd add those codes together (2 and 4) to get 6.  All other attribute codes (except for volume label) are normally inclusive. For example, specifying both hidden and system results in DIR$ returning all hidden files, system files, normal files, and files that are both hidden and system.

If the ONLY option is included, normal files are excluded from the file search.  For example: DIR$(mask$, ONLY 16) just the directory entries which match mask$ are returned.  Another useful search attribute is 6, which returns normal, hidden, and system file, but no directories.

An attribute of 8 will return the volume label, if one exists.  In this case, mask$ must reference the drive letter of the target drive, and additional path information is ignored.  Additionally, you may specify a UNC name for a shared drive (subject to operating system restrictions), and retrieve the volume label, if one exists, and you have suitable access rights.  You can also obtain the volume label for a 'hidden' share with NT/2000/XP by appending a trailing dollar symbol to the share name.

' Retrieve volume for share \\server\drive0
A$ = DIR$("\\server\drive0", 8)

' Retrieve volume for hidden share D: (\d$)
A$ = DIR$("\\server\d$", %VLABEL)

The DIR$ function may optionally assign the complete directory entry to an appropriate UDT variable if you include the TO clause as a parameter. The complete directory entry contains 318 bytes of data, corresponding to the following TYPE definition.  This definition (DIRDATA) is built into PowerBASIC, and need not necessarily be included in your source code.

TYPE DirData
  FileAttributes        AS DWORD
  CreationTime          AS QUAD
  LastAccessTime        AS QUAD
  LastWriteTime         AS QUAD
  FileSizeHigh          AS DWORD
  FileSizeLow           AS DWORD
  Reserved0             AS DWORD
  Reserved1             AS DWORD
  FileName              AS ASCIIZ * 260
  ShortName             AS ASCIIZ * 14
END TYPE

You can declare a variable as DIRDATA for this purpose, or use any other user-defined type of at least 318 data bytes.  The additional data may be used for any other purpose in your program.

Restrictions

PowerBASIC performs file matching with both the long (LFN) and short (SFN) filename versions of filenames.  This means that DIR$ will also return filenames that start with the specified extension (as per standard Windows operating system behavior).

For example, A$ = DIR$("*.htm") will match filenames such as "Index.htm", "Default.html", "Homepages.htmb", "cgilib.htmlpages", etc.  Similarly, A$ = DIR$("*.h??") and DIR$("*.ht*") will match the same filenames.

DIR$ is thread-safe, so DIR$ operations in one thread do not interfere with DIR$ operations in another thread.

However, you should be aware that changing the mask during a DIR$ search loop (within the same thread) will affect the search loop operation.  That is, if a typical DIR$ search loop block such as shown in the Example code below, changes the search mask mid-way through the loop, subsequent calls to DIR$ will begin to return files matching the new mask.

This is rarely a problem if the mask change takes place within the search loop code block, since the DIR$("mask") change will be plainly visible in the loop block code.  However, the mask can also be changed from within a Sub/Function/Method/Property that is called from within the search loop block (provided that the procedure is located within the same compiled module).

While such techniques are perfectly valid, the cause of the mask change may not be immediately obvious when viewing just the search loop code block.  PowerBASIC allows the mask to be changed in this manner, since it may be an intended behavior on the part of the programmer, but in doing so, it opens up the potential for subtle bugs to be introduced into your code if this technique is not anticipated.

See also

CURDIR$, DIR$ CLOSE, FILEATTR, GETATTR, ISFILE, PATHNAME$, PATHSCAN$, SETATTR

Example

The following code shows a typical method of retrieving filenames from a directory:

DIM Listing$(1 TO 1000)
DIM x&, temp$
temp$ = DIR$("*.*", TO Listing(x&) )
WHILE LEN(temp$) AND x& < 1000 ' max = 1000
  INCR x&
  temp$ = DIR$(NEXT, TO Listing(x&) )
WEND