[ Operating System | Reference Manual | Alphabetic Index ]

# read_directory(+Directory, +Pattern, -SubdirList, -FileList)

Unifies SubdirList with a list of subdirectories and FileList with a list of matching files in the specified directory.

Directory
  Atom or String
Pattern
  Atom or String
SubdirList
  Free variable or (maybe partial) list of strings
FileList
  Free variable or (maybe partial) list of strings

## Description

read_directory/4 scans the directory specified by Directory. It collects the names of the subdirectories in SubdirList and the names of the files matching Pattern in FileList. SubdirList and FileList are lists of strings. Pattern is a string containing a filename specification similar to the usual UNIX convention. The metacharacters recognised are: * matches an arbitrary sequence of characters, ? matches any single character, [] matches one of the characters inside the brackets unless the first one is a ^ in which case it matches any character but those inside the brackets.

Filenames beginning with a dot are not suppressed by default, but the directories "." and ".." are omitted from SubdirList.

### Modes and Determinism

- read_directory(+, +, -, -) is det

### Exceptions

(4) instantiation fault
  Directory or Pattern is not instantiated.
(5) type error
  Directory or Pattern is neither atom nor string.
(5) type error
  SubdirList or FileList are instantiated, but not to lists.
(170) system interface error
  An error occurred trying to access Directory.

## Examples

       Success:
       [eclipse]: read_directory("/usr/john", "*", Dirlist, Filelist).
       Dirlist = ["subdir1", "subdir2"]
       Filelist = ["one.c", "two.c", "three.pl", "four.pl"]
       yes.
       [eclipse]: read_directory(., "[^t]*.pl", Dirlist, Filelist).
       Dirlist = ["subdir1", "subdir2"]
       Filelist = ["four.pl"]
       yes.
       Fail:
       [eclipse]: read_directory(".", "*.c", _, ["one.c"]).
       no.
       Error:
       read_directory(_, "*", Dirs, Files).          (error 4)
       read_directory([46], "*", Dirs, Files).       (error 5)
       read_directory(".", _, Dirs, Files).          (error 4)
       read_directory(".", 3, Dirs, Files).          (error 5)
       read_directory(".", "*.pl", Dirs, file).      (error 5)
       read_directory("/private", "*", _, Files).    (error 170)

        % EXAMPLE: find_tree(+Root, +Pattern, -ListOfRelativeFiles)
        % Recursively find all files matching Pattern below the directory
        % or list of directories Roots.

        find_tree(Root, Pattern, AllFiles) :- (atom(Root);string(Root)), !,
    	    find_dir(Root, "", "", Pattern, AllFiles, []).
        find_tree(Roots, Pattern, AllFiles) :-
    	    find_tree(Roots, Pattern, AllFiles, []).

        find_tree([], _Pattern, AllFiles, AllFiles).
        find_tree([Root|Roots], Pattern, AllFiles, AllFiles0) :-
    	    find_dir(Root, "", "", Pattern, AllFiles, AllFiles1),
    	    find_tree(Roots, Pattern, AllFiles1, AllFiles0).

        find_dir(_, _, [], _, AllFiles, AllFiles) :- !.
        find_dir(Root, RelPath, [Dir|Dirs], Pattern, AllFiles, AllFiles0) :- !,
    	    find_dir(Root, RelPath, Dir, Pattern, AllFiles, AllFiles1),
    	    find_dir(Root, RelPath, Dirs, Pattern, AllFiles1, AllFiles0).
        find_dir(Root, RelPath, Dir, Pattern, AllFiles, AllFiles0) :-
    	    ( RelPath=="" -> RelDir=Dir
    	    ; concat_string([RelPath,/,Dir], RelDir) ),
    	    ( RelDir=="" -> AbsDir=Root
    	    ; concat_string([Root,/,RelDir], AbsDir) ),
    	    read_directory(AbsDir, Pattern, SubDirs, Files),
    	    find_files(Root, RelDir, Files, AllFiles, AllFiles1),
    	    find_dir(Root, RelDir, SubDirs, Pattern, AllFiles1, AllFiles0).

        find_files(_, _, [], AbsFiles, AbsFiles).
        find_files(Root, RelDir, [File|Files], [AbsFile|AbsFiles], AbsFiles0) :-
    	    ( RelDir=="" -> concat_string([Root,/,File], AbsFile)
    	    ; concat_string([Root,/,RelDir,/,File], AbsFile) ),
    	    find_files(Root, RelDir, Files, AbsFiles, AbsFiles0).

## See Also

cd / 1, getcwd / 1, get_flag / 2, pathname / 4, existing_file / 4, exists / 1, mkdir / 1