The basic directory scanning routine is
is true when
Directory can be an absolute filename or a relative one. FullName will be absolute if Directory is absolute, relative if Directory is relative.
We return the FileName component because that is the component on which pattern matching is generally done. We return the FullName component in order to remove from the user the burden of manipulating the (system-dependent) rules for putting together a directory name and a file name.
This predicate acts as much like a logical relation as it can. Here are some of the ways of using it:
| ?- file_member_of_directory(foo, Name, Full), write(Name=Full), nl, fail. % to enumerate members of the directory | ?- file_member_of_directory(baz, 'ugh.pl', Full). % to test whether a file 'ugh.pl' is visible in % directory 'baz', and if so return the full name | ?- file_member_of_directory(Dir, Nam, 'baz/jar.log'). % if there is a visible regular file baz/jar.log, % to return its directory in Dir and name in Nam.
file_member_of_directory/3 has two variants:
file_member_of_directory/3, except that it checks the current directory. You could obtain this effect quite easily by calling
file_member_of_directory/3with first argument
., but in other operating systems the current directory is denoted differently. This provides an operating-system-independent way of searching the current directory. There is one other difference, which is of great practical importance:
.is a relative directory name, but
file_member_of_directory/2uses the absolute name for the current directory, so that the FullName you get back will also be absolute. See the description of
absolute_file_name/2in the reference pages. Note the difference between calling
The former will accept any filename, but the FileName
must be instantiated. The latter will only accept simple file
names with no directory component, and insists that the file must
already exist, but in return will generate FileName.
file_member_of_directory/3, except that it filters out all the FileNames that do not match Pattern. Pattern is an atom that may contain
?matches any character and
*matches any sequence of characters (cf. UNIX
sh(1)). The main use for this routine is to select files with a particular extension. Thus,
| ?- file_member_of_directory(foo,'*.pl',Short,Full).
To summarize, the three routines discussed so far are
file_member_of_directory([Directory, [Pattern, ]]Short, Full)
They enumerate FileName-FullName pairs one at a time: in alphabetic order, as it happens.
There is another set of three predicates finding exactly the
same solutions, but returning them as a set of FileName-FullName
pairs. We follow here the general convention that predicates that return one
thing in their name, and predicates that
return the set of "things" have
things in their name.
| ?- file_member_of_directory(foo, '*.pl', S, F). S = 'bat.pl', F = 'foo/bat.pl' ; S = 'fly.pl', F = 'foo/fly.pl' ; no
one would find
| ?- file_members_of_directory(foo, '*.pl', Set). Set = ['bat.pl'-'foo/bat.pl', 'fly.pl'-'foo/fly.pl']