There are two sets of file manipulation predicates in SICStus Prolog. One set is inherited from DEC-10 Prolog. These predicates always refer to a file by specification. The other set of predicates is modeled after Quintus Prolog and refer to files as streams. Streams correspond to the file pointers used at the operating system level.
This second set of file manipulation predicates, the one involving streams, is supported by the ISO Prolog standard. Note that the notion of file is used here in a generalized sense; it may refer to a named file, the user's terminal, or some other device. The ISO Prolog standard refers to this generalized notion of file using the term source/sink.
A stream can be opened and connected to a file specification
or file descriptor for input or output by calling the predicates
open/[3,4]
. These predicates will return a reference to a
stream, which may then be passed as an argument to various
I/O predicates. Alternatively, a stream can be assigned an
alias at the time of opening, and referred to by this alias
afterwards. The predicate close/1
is used for closing a
stream.
There are two types of streams, binary or text. Binary streams are seen as a sequence of bytes, i.e. integers in the range 0-255. Text streams, on the other hand, are considered a sequence of characters, represented by their character codes. SICStus Prolog handles wide characters, i.e. characters with codes larger than 255. The WCX (Wide Character eXtension) component of SICStus Prolog allows selecting various encoding schemes via environment variables or hook predicates; see Handling Wide Characters.
The predicates current_stream/3
and
stream_property/2
are used for retrieving information about a
stream, and for finding the currently existing streams.
Prolog streams can be accessed from C functions as well. See SICStus Streams, for details.
The possible formats of a stream are:
'$stream'(
X)
alias(
Atom)
option of
open/4
. There are also three predefined aliases:
user_input
stdin
stream. The alias can be changed with prolog_flag/3
and accessed by the C variable SP_stdin
.
user_output
stdout
stream. The alias can be changed with prolog_flag/3
and accessed by the C variable SP_stdout
.
user_error
stderr
stream. The alias can be changed with prolog_flag/3
and accessed by the C variable SP_stderr
.
This stream is used by the Prolog top-level and debugger, and for system messages.
Certain I/O predicates manipulate streams implicitly, by
maintaining the notion of a current input stream and a
current output stream. The current input and output streams
are set to the user_input
and user_output
initially and
for every new break (see Nested). The predicate see/1
(tell/1
) can be used for setting the current input (output)
stream to newly opened streams for particular files. The
predicate seen/0
(told/0
) closes the current input
(output) stream, and resets it to the standard input (output)
stream. The predicate seeing/1
(telling/1
) is
used for retrieving the file name associated with the current input
(output) streams.
The file specification user
stands for the standard input
or output stream, depending on context. Terminal output is only
guaranteed to be displayed if the output stream is explicitly
flushed.
A file specification FileSpec other than user
must be
an atom or a compound term. It is subject to syntactic
rewriting. Depending on the operation, the resulting absolute filename
is subject to further processing. Syntactic rewriting is
performed wrt. a context directory Context, in the follows
steps:
Path(
File)
, it is
rewritten by first looking up a clause of the hook predicate
user:file_search_path(
Path,
Expansion)
. If such
a clause is found, and Expansion can be rewritten to the
atomic file name FirstPart, and File can be rewritten
to the atomic file name SecondPart, then FileSpec is
rewritten to
FirstPart/
SecondPart
.
\
characters are converted to /
.
/
s in the file name.
/
.
/
-groups (where a /
-group is defined to be
a sequence of one or more /
s with no non-/
character interspersed.)
Each /
-group is replaced by a single /
.
Under Windows, however, a //
prefix is not replaced by a single /
.
/
and the end of the file name.
To give the absolute file name, the following rules are applied to each component of FileSpec.
~
user
, if encountered as the first component
of FileSpec, is replaced by the absolute path
of the home directory of user. If user doesn't exist,
a permission error is raised.
Not yet applicable under Windows.
~
, if encountered as the first component
of FileSpec, is replaced by the absolute path
of the home directory of the current user.
Under Windows, ~
is replaced
by the user's home directory using the environment variables
HOMEDRIVE
and HOMEPATH
.
$
var
, if encountered as the first component
of FileSpec, is replaced by the value
of the environment variable var. If var doesn't exist,
a permission error is raised.
.
is deleted.
..
is deleted together with the directory name
syntactically preceding it. For example, a/b/../c
is
rewritten as a/c
.
/
is deleted.
//
hostname/
sharename/
...
or begins with a drive letter followed by :
.
For example, asssuming the user's home directory is /users/clyde
and given the clauses
file_search_path(home, '$HOME'). file_search_path(demo, home(prolog(demo))). file_search_path(prolog, prolog).
the file specification demo(mydemo)
would be rewritten to
'/users/clyde/prolog/demo/mydemo'
, since $HOME
is
interpreted as an environment variable (Under UNIX, this is the user's home
directory).
Failure to open a file normally causes an exception to be raised. This
behavior can be turned off and on by of the built-in predicates
nofileerrors/0
and fileerrors/0
described below.