Home Contents Index Summary Previous Next

3.15 Input and Output

SWI-Prolog provides two different packages for input and output. One confirms to the Edinburgh standard. This package has a notion of `current-input' and `current-output'. The reading and writing predicates implicitly refer to these streams. In the second package, streams are opened explicitly and the resulting handle is used as an argument to the reading and writing predicate to specify the source or destination. Both packages are fully integrated; the user may switch freely between them.

3.15.1 Input and Output Using Implicit Source and Destination

The package for implicit input and output destination is upwards compatible to DEC-10 and C-Prolog. The reading and writing predicates refer to resp. the current input- and output stream. Initially these streams are connected to the terminal. The current output stream is changed using tell/1 or append/1. The current input stream is changed using see/1. The streams current value can be obtained using telling/1 for output- and seeing/1 for input streams. The table below shows the valid stream specifications. The reserved names user_input, user_output and user_error are for neat integration with the explicit streams.

user This reserved name refers to the terminal
user_input Input from the terminal
user_output Output to the terminal
user_error Unix error stream (output only)
<Atom> Name of a Unix file
pipe(<Atom>) Name of a Unix command

Source and destination are either a file, one of the reserved words above, or a term `pipe(Command)'. In the predicate descriptions below we will call the source/destination argument `SrcDest'. Below are some examples of source/destination specifications.

?- see(data). % Start reading from file `data'.
?- tell(stderr). % Start writing on the error stream.
?- tell(pipe(lpr)). % Start writing to the printer.

Another example of using the pipe/1 construct is shown below. Note that the pipe/1 construct is not part of Prolog's standard I/O repertoire.


getwd(Wd) :-
        seeing(Old), see(pipe(pwd)), 
        collect_wd(String), 
        seen, see(Old), 
        atom_chars(Wd, String).

collect_wd([C|R]) :-
        get0(C), C \== -1, !, 
        collect_wd(R).
collect_wd([]).

see(+SrcDest)
Make SrcDest the current input stream. If SrcDest was already opened for reading with see/1 and has not been closed since, reading will be resumed. Otherwise SrcDest will be opened and the file pointer is positioned at the start of the file.

tell(+SrcDest)
Make SrcDest the current output stream. If SrcDest was already opened for writing with tell/1 or append/1 and has not been closed since, writing will be resumed. Otherwise the file is created or---when existing---truncated. See also append/1.

append(+File)
Similar to tell/1, but positions the file pointer at the end of File rather than truncating an existing file. The pipe construct is not accepted by this predicate.

seeing(?SrcDest)
Unify the name of the current input stream with SrcDest.

telling(?SrcDest)
Unify the name of the current output stream with SrcDest.

seen
Close the current input stream. The new input stream becomes user.

told
Close the current output stream. The new output stream becomes user.

3.15.2 Explicit Input and Output Streams

The predicates below are part of the Quintus compatible stream-based I/O package. In this package streams are explicitly created using the predicate open/3. The resulting stream identifier is then passed as a parameter to the reading and writing predicates to specify the source or destination of the data.

open(+SrcDest, +Mode, -Stream, +Options)
ISO compliant predicate to open a stream. SrcDes is either an atom, specifying a Unix file, or a term `pipe(Command)', just like see/1 and tell/1. Mode is one of read, write, append or update. Mode append opens the file for writing, positioning the file-pointer at the end. Mode update opens the file for writing, positioning the file-pointer at the beginning of the file without truncating the file. See also stream_position/3. Stream is either a variable, in which case it is bound to an integer identifying the stream, or an atom, in which case this atom will be the stream identifier. The Options list can contain the following options:

type(Type)
Using type text (default), Prolog will write a text-file in an operating-system compatible way. Using type binary the bytes will be read or written without any translation. Note there is no difference between the two on Unix systems.

alias(Atom)
Gives the stream a name. The following two calls are identical, but only the latter is allowed in ISO Prolog.


?- open(foo, read, in, []).
?- open(foo, read, S, [alias(in)]).

eof_action(Action)
Defines what happens if the end of the input stream is reached. Action eof_code makes get0/1 and friends return -1 and read/1 and friends return the atom end_of_file. Repetitive reading keeps yielding the same result. Action error is like eof_code, but repetitive reading will raise an error. With action reset, Prolog will examine the file again and return more data if the file has grown.

buffer(Buffering)
Defines output buffering. The atom fullf (default) defines full buffering, line buffering by line, and false implies the stream is fully unbuffered. Smaller buffering is useful if another process or the user is waiting for the output as it is being produced. See also flush/0 and flush_output/1. This option is not an ISO option.

close_on_abort(Bool)
If true (default), the stream is closed on an abort (see abort/0). If false, the stream is not closed. If it is an output stream, it will be flushed however. Useful for logfiles and if the stream is associated to a process (using the pipe/1 construct).

The option reposition is not supported in SWI-Prolog. All streams connected to a file may be repositioned.

open(+SrcDest, +Mode, ?Stream)
Equivalent to open/4 with an empty option-list.

open_null_stream(?Stream)
Open a stream that produces no output. All counting functions are enabled on such a stream. An attempt to read from a null-stream will immediately signal end-of-file. Similar to Unix /dev/null. Stream can be an atom, giving the null-stream an alias name.

close(+Stream)

Close the specified stream. If Stream is not open an error message is displayed. If the closed stream is the current input or output stream the terminal is made the current input or output.

current_stream(?File, ?Mode, ?Stream)
Is true if a stream with file specification File, mode Mode and stream identifier Stream is open. The reserved streams user and user_error are not generated by this predicate. If a stream has been opened with mode append this predicate will generate mode write.

stream_position(+Stream, -Old, +New)
Unify the position parameters of Stream with Old and set them to New. A position is represented by the following term:


'$stream_position'(CharNo, LineNo, LinePos).

It is only possible to change the position parameters if the stream is connected to a disk file. If the position is changed, the CharNo field determines the new position in the file. The LineNo and LinePos are copied in the stream administration. See also seek/4.

seek(+Stream, +Offset, +Method, -NewLocation)
Reposition the current point of the given Stream. Method is one of bof, current or eof, indicating positioning relative to the start, current point or end of the underlying object. NewLocation is unified with the new offset, relative to the start of the stream.

If the seek modifies the current location, the line number and character position in the line are set to 0.

If the stream cannot be repostioned, a reposition error is raised. The predicate seek/4 is compatible to Quintus Prolog, though the error conditions and signalling is ISO compliant. See also stream_position/3.

3.15.3 Switching Between Implicit and Explicit I/O

The predicates below can be used for switching between the implicit- and the explicit stream based I/O predicates.

set_input(+Stream)
Set the current input stream to become Stream. Thus, open(file, read, Stream), set_input(Stream) is equivalent to see(file).

set_output(+Stream)
Set the current output stream to become Stream.

current_input(-Stream)
Get the current input stream. Useful to get access to the status predicates associated with streams.

current_output(-Stream)
Get the current output stream.

dup_stream(+From, +To)
Duplicate the underlying data from stream From to streamTo, so actions performed on either stream have the same effect. The primary goal of this predicate is to facilitate redirection of the user interaction to allow for `interactor' windows. For example, the following code will redirect output to user_output and user_error to an XPCE text window:


        ...,
        pce_open(Window, append, Fd),
        dup_stream(user_output, Fd),
        dup_stream(user_error, Fd),
        ...

The old status of a stream can be stored by duplicating to a null-stream as obtained using open_null_stream/1.

This predicate is SWI-Prolog specific.